www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to make private class member private

reply psychoticRabbit <meagain meagain.com> writes:
I cannot get my head around, why private is not private, in D.

How do I make a private member, private?

-----
module test;

import std.stdio;

void main()
{
     myClass c = new myClass();
     c.myPrivateClassMember= "wtf";
     writeln(c.myPrivateClassMember);
}

class myClass
{
     private string myPrivateClassMember; // private does not mean 
private anymore??
}

------
Mar 12 2018
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
Visibility modifiers in D are for the module, not class or struct.

This is very useful to be able to access internal stuff outside of the 
abstraction and modify it sanely. While also keeping others at bay.
Mar 12 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, March 13, 2018 01:12:15 psychoticRabbit via Digitalmars-d-learn 
wrote:
 I cannot get my head around, why private is not private, in D.

 How do I make a private member, private?

 -----
 module test;

 import std.stdio;

 void main()
 {
      myClass c = new myClass();
      c.myPrivateClassMember= "wtf";
      writeln(c.myPrivateClassMember);
 }

 class myClass
 {
      private string myPrivateClassMember; // private does not mean
 private anymore??
 }

 ------
private is private to the module, not the class. There is no way in D to restrict the rest of the module from accessing the members of a class. This simplification makes it so that stuff like C++'s friend are unnecessary. If your class in a separate module from main, then main won't be able to access its private members. - Jonathan M Davis
Mar 12 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote:
 private is private to the module, not the class. There is no 
 way in D to restrict the rest of the module from accessing the 
 members of a class. This simplification makes it so that stuff 
 like C++'s friend are unnecessary. If your class in a separate 
 module from main, then main won't be able to access its private 
 members.

 - Jonathan M Davis
Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all.
Mar 12 2018
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 13 March 2018 at 02:06:57 UTC, psychoticRabbit wrote:
 Mmm.. I don't think I like it.

 I feel you should be able to make a member of a class, private, 
 regardless of where the class is located. This seems to break 
 the concept of class encapsulation.

 No. I don't like it at all.
If you have access to the module source, you have access to the source of types inside it. Making the module the lowest level of encapsulation makes sense from that perspective.
Mar 12 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 02:24:38 UTC, Mike Parker wrote:
 On Tuesday, 13 March 2018 at 02:06:57 UTC, psychoticRabbit 
 wrote:
 Mmm.. I don't think I like it.

 I feel you should be able to make a member of a class, 
 private, regardless of where the class is located. This seems 
 to break the concept of class encapsulation.

 No. I don't like it at all.
If you have access to the module source, you have access to the source of types inside it. Making the module the lowest level of encapsulation makes sense from that perspective.
There are two problems I see: 1st - D has broken the concept of class encapsulation, simply for convenience at the module level. Not good in my opinion. syntax, but get very different semantics. Not good in my opinion. (i.e. I only realised private was not private, by accident). D has made many good design decisions. I do not see this as one of them.
Mar 12 2018
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
psychoticRabbit wrote:

 There are two problems I see:
1) it is not how C++ done it. 2) it is not how C++ done it. and you're completely right: it is not how C++ done it.
Mar 12 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 05:52:55 UTC, ketmar wrote:
 psychoticRabbit wrote:

 There are two problems I see:
1) it is not how C++ done it. 2) it is not how C++ done it. and you're completely right: it is not how C++ done it.
umm...didn't you forget something: 1) it is not how Java done it. 2) it is not how Java done it.
Mar 12 2018
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
psychoticRabbit wrote:

 On Tuesday, 13 March 2018 at 05:52:55 UTC, ketmar wrote:
 psychoticRabbit wrote:

 There are two problems I see:
1) it is not how C++ done it. 2) it is not how C++ done it. and you're completely right: it is not how C++ done it.
umm...didn't you forget something: 1) it is not how Java done it. 2) it is not how Java done it.
java. mea maxima culpa!
Mar 12 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 06:01:43 UTC, ketmar wrote:
 ah, yes, sorry: i completely forgot that C++ was invented after 

My point was, that the 2 most widely used and popular languages mean else, like D has done. So the 3 most used languages got it wrong??
Mar 12 2018
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
psychoticRabbit wrote:

 So the 3 most used languages got it wrong??
yes.
Mar 12 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 06:25:39 UTC, ketmar wrote:
 psychoticRabbit wrote:

 So the 3 most used languages got it wrong??
yes.
do you know any other language, where a private class memeber, is not private to the class? (btw. that's a question, not a statement).
Mar 12 2018
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
psychoticRabbit wrote:

 On Tuesday, 13 March 2018 at 06:25:39 UTC, ketmar wrote:
 psychoticRabbit wrote:

 So the 3 most used languages got it wrong??
yes.
do you know any other language, where a private class memeber, is not private to the class? (btw. that's a question, not a statement).
that is, we should stick to defective design only 'cause there is no "other D" that made it right? ;-) also, your question is not valid. you were told several times that you're evaluating the whole thing wrong, but you're insisting on your view being right. and you're keep asking, omiting the *critical* piece of the picture: modules. you were told that in D, encapsulation unit is *module*, not class/struct. it is not a "misdesign", it is the proper modular design. it doesn't matter what others are doing in this case. p.s.: yes, i know such language. Delphi/FreePascal.
Mar 12 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 06:43:55 UTC, ketmar wrote:
 that is, we should stick to defective design only 'cause there 
 is no "other D" that made it right? ;-)

 also, your question is not valid. you were told several times 
 that you're evaluating the whole thing wrong, but you're 
 insisting on your view being right. and you're keep asking, 
 omiting the *critical* piece of the picture: modules. you were 
 told that in D, encapsulation unit is *module*, not 
 class/struct. it is not a "misdesign", it is the proper modular 
 design. it doesn't matter what others are doing in this case.

 p.s.: yes, i know such language. Delphi/FreePascal.
Gee.. I feel like I'm on a Rust forum, being attacked my their sjw moderators. Whatever happened to the 'discussion' component of these 'discussions'?
Mar 13 2018
parent ketmar <ketmar ketmar.no-ip.org> writes:
psychoticRabbit wrote:

 Whatever happened to the 'discussion' component of these 'discussions'?
dunno. try to ask yourself, why repeating the same point again and again when you were given the answer and the rationale doesn't make a good discussion.
Mar 13 2018
prev sibling next sibling parent reply Radu <void null.pt> writes:
On Tuesday, 13 March 2018 at 06:14:49 UTC, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 06:01:43 UTC, ketmar wrote:
 ah, yes, sorry: i completely forgot that C++ was invented 

My point was, that the 2 most widely used and popular languages something mean else, like D has done. So the 3 most used languages got it wrong??
Yes, they got it wrong! Because they don't have modules, and preach that the world spins on classes. C++ tried to fix it with 'friend', and it shows the hack that it is.
Mar 12 2018
parent psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 06:26:13 UTC, Radu wrote:
 On Tuesday, 13 March 2018 at 06:14:49 UTC, psychoticRabbit 
 wrote:
 On Tuesday, 13 March 2018 at 06:01:43 UTC, ketmar wrote:
 ah, yes, sorry: i completely forgot that C++ was invented 

My point was, that the 2 most widely used and popular private, something mean else, like D has done. So the 3 most used languages got it wrong??
Yes, they got it wrong! Because they don't have modules, and preach that the world spins on classes. C++ tried to fix it with 'friend', and it shows the hack that it is.
Well I don't really. But one of the great things about D, is that But when the same syntax suddenly means something really different, I tend to think that's not a good design decision. And that's really the main point of my argument. As I said, this was a real gotcha for me. I only realised after I accidently tried to modify a private member directly, and discovered I did actually modify it! Maybe, a different modifier that made it private to the module would have been a better design decision.
Mar 12 2018
prev sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 13/03/2018 7:14 PM, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 06:01:43 UTC, ketmar wrote:

 java. mea maxima culpa!
My point was, that the 2 most widely used and popular languages on the like D has done. So the 3 most used languages got it wrong??
Yes. Module system comes from the ML family. As proven by the adoption by Java as of late, it is far superior to alternative designs.
Mar 12 2018
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 13 March 2018 at 05:11:48 UTC, psychoticRabbit wrote:

 1st - D has broken the concept of class encapsulation, simply 
 for convenience at the module level. Not good in my opinion.
No, it hasn't broken encapsulation. Encapsulation is at the module level. A class or struct and any supporting functions can be included in a single module and the private API is encapsulated from the outside world.

 syntax, but get very different semantics. Not good in my 
 opinion. (i.e. I only realised private was not private, by 
 accident).
 D has made many good design decisions. I do not see this as one 
 of them.
I think it's a great feature and I use it frequently. It's allows more flexibility in class design. Without it, we'd need another protection attribute to enable the concept of "private to the module". In Java, it's recommended to manipulate private member variables through their accessors even in methods of the same class. I've always found that extreme. If you need to make a breaking change to the member variable, you already have access to all of the method internals anyway. Yes, there's room for error if you forget to make a change, but with all the support in modern IDEs and editors for find/replace, it's a simple matter to handle it all at once. And in the standard edit-compile-run cycle, any breakage is discovered right away, not weeks down the road in the field. The same applies here. Encapsulation simply isn't broken by this feature.
Mar 12 2018
next sibling parent psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:
 I think it's a great feature and I use it frequently. It's 
 allows more flexibility in class design. Without it, we'd need 
 another protection attribute to enable the concept of "private 
 to the module".
That's kind of my point. That's what I would have done, if for no other reason, to prevent the same syntax from having different And I switch between them all, and now, I have to remember D's private memeber is something very different indeed.
 In Java, it's recommended to manipulate private member 
 variables through their accessors even in methods of the same 
 class. I've always found that extreme.
Java is extreme in many ways ;-) but at least, private member, is still a private member (to the class). If my private class memeber can be directly modified outside of the class, then class encapsulation IS broken. Just saying, oh no, it's module encapsulation you should be thinking about, seems kinda strange, since we still use classes - which are their own level of encapsulation. That's the whole point of them.
Mar 12 2018
prev sibling next sibling parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:
 The same applies here. Encapsulation simply isn't broken by 
 this feature.
What you're saying, is in D, class encapsulation is really 'module' encapsulation. I get it. Fine. It's an intersting design decision. But, in doing that, D has shifted the boundary of class encapsulation, to a boundary that is outside the class. To me, that sounds like D has broken class encapsulation. I don't know how else one could describe it. I continue to think, that class encapsulation is sacred, a well defined, well understood, concept that has been around for a very long time. private could have still meant private, and surely someone could have come up with a different access modifier to mean 'private at module level'. Was that too hard the language designers? Was it not hard, but just to complex to implement? I don't get it.
Mar 12 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
Your thought model is much younger than modules. Modules have existed 
since the mid 70's.
They work, other designs over the years have proven to have faults and 
problems.

D's design is evolved from already existing ideas to try and give the 
best of both worlds and modules is no different.

The reality is, Java and C++ both are great examples where module system 
was added after many years too late. D had it built in from the get go 
and was designed to benefit from it.
Mar 13 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 07:05:48 UTC, rikki cattermole wrote:
 Your thought model is much younger than modules. Modules have 
 existed since the mid 70's.
 They work, other designs over the years have proven to have 
 faults and problems.

 D's design is evolved from already existing ideas to try and 
 give the best of both worlds and modules is no different.

 The reality is, Java and C++ both are great examples where 
 module system was added after many years too late. D had it 
 built in from the get go and was designed to benefit from it.
I don't have any objection to the idea that a module can have privileged access to members of classes within that model. It sounds sensible enough, if the module is a level of encapsulation also. My arguments is that, this was implemented in D, at the cost of removing the capacity for a class in the same module to protect it's own members (within the module). That's what I don't like about it. My other objection, as stated, is that D uses the same syntax as different. I also don't like that.
Mar 13 2018
parent reply Alex <sascha.orlov gmail.com> writes:
On Tuesday, 13 March 2018 at 07:39:04 UTC, psychoticRabbit wrote:
 I don't have any objection to the idea that a module can have 
 privileged access to members of classes within that model. It 
 sounds sensible enough, if the module is a level of 
 encapsulation also.

 My arguments is that, this was implemented in D, at the cost of 
 removing the capacity for a class in the same module to protect 
 it's own members (within the module). That's what I don't like 
 about it.

 My other objection, as stated, is that D uses the same syntax 

 completely different. I also don't like that.
If you are missing more fine grained encapsulation control: take a look at https://wiki.dlang.org/Access_specifiers_and_visibility#package If you are in debt, that encapsulation at module level is more superior with respect to encapsulation and expressiveness in comparison to class level, look at Fortran and Java 9. And last but not least: ´´´ package myPackage; public class Main { public static void main(String[] args) { System.out.println("Hello World!"); myClass c = new myClass(); c.myPrivateClassMember= "wtf"; System.out.println(c.myPrivateClassMember); } private static class myClass { private String myPrivateClassMember; // private does not mean private anymore?? } } ´´´ (may the forum forgive me :p )
Mar 13 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 08:29:42 UTC, Alex wrote:
 package myPackage;

 public class Main {

     public static void main(String[] args)
     {
         System.out.println("Hello World!");
         myClass c = new myClass();
         c.myPrivateClassMember= "wtf";
         System.out.println(c.myPrivateClassMember);
     }

     private static class myClass
     {
         private String myPrivateClassMember; // private does 
 not mean private anymore??
     }
 }
 ´´´
 (may the forum forgive me :p )
But a class and its inner classes together, can be still be reasoned about locally. With 'modules', the boundaries of what 'local' means, becomes more and more fuzzy, as the module gets longer and longer, and more and more complex. In those circumstances, it becomes much harder to reason locally about the correctness of a class. And a D module can go on..well...for ever..... I would still prefer that classes within a module, at least have a capacity to specify access privileges to objects in the same module, rather than just trusting everything in that module, without exception.
Mar 13 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 14/03/2018 12:19 AM, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 08:29:42 UTC, Alex wrote:
 package myPackage;

 public class Main {

     public static void main(String[] args)
     {
         System.out.println("Hello World!");
         myClass c = new myClass();
         c.myPrivateClassMember= "wtf";
         System.out.println(c.myPrivateClassMember);
     }

     private static class myClass
     {
         private String myPrivateClassMember; // private does not mean 
 private anymore??
     }
 }
 ´´´
 (may the forum forgive me :p )
But a class and its inner classes together, can be still be reasoned about locally. With 'modules', the boundaries of what 'local' means, becomes more and more fuzzy, as the module gets longer and longer, and more and more complex. In those circumstances, it becomes much harder to reason locally about the correctness of a class. And a D module can go on..well...for ever..... I would still prefer that classes within a module, at least have a capacity to specify access privileges to objects in the same module, rather than just trusting everything in that module, without exception.
Ah yes. You're completely correct if you subscribe to Adam's and ketmar's file sizes expectation. A D module and package is one level of abstraction. If that level of abstraction starts to fill up and gets large, you split it up. My rule is soft 1k LOC and hard 2-3k (after that it needs a VERY good reason to stay together). This makes each file to be very right down to the point and do nothing else. You should be doing this no matter the language IMO. Just the difference is in Java only one class is publicly accessible per file. Nothing stops you from doing that here either.
Mar 13 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 11:31:12 UTC, rikki cattermole wrote:
 Ah yes.
 You're completely correct if you subscribe to Adam's and 
 ketmar's file sizes expectation.

 A D module and package is one level of abstraction. If that 
 level of abstraction starts to fill up and gets large, you 
 split it up.

 My rule is soft 1k LOC and hard 2-3k (after that it needs a 
 VERY good reason to stay together).

 This makes each file to be very right down to the point and do 
 nothing else.

 You should be doing this no matter the language IMO. Just the 
 difference is in Java only one class is publicly accessible per 
 file. Nothing stops you from doing that here either.
Fair enough. I doubt I'll use your 'lines of code' method as a means of encapsulation though ;-) I have to think more, about what a module is really trying to encapsulate. I'm sure there is a good blog that could come out of this conversation. (not by me though)
Mar 13 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 14/03/2018 1:02 AM, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 11:31:12 UTC, rikki cattermole wrote:
 Ah yes.
 You're completely correct if you subscribe to Adam's and ketmar's file 
 sizes expectation.

 A D module and package is one level of abstraction. If that level of 
 abstraction starts to fill up and gets large, you split it up.

 My rule is soft 1k LOC and hard 2-3k (after that it needs a VERY good 
 reason to stay together).

 This makes each file to be very right down to the point and do nothing 
 else.

 You should be doing this no matter the language IMO. Just the 
 difference is in Java only one class is publicly accessible per file. 
 Nothing stops you from doing that here either.
Fair enough. I doubt I'll use your 'lines of code' method as a means of encapsulation though ;-)
The number of lines of code is more of a code smell which suggests that the module is going out of scope in size and functionality.
 I have to think more, about what a module is really trying to encapsulate.
 
 I'm sure there is a good blog that could come out of this conversation.
 (not by me though)
While it is new to some people, we would only be rehashing existing ideas that have existed in the literature for 40+ years.
Mar 13 2018
parent psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 12:10:07 UTC, rikki cattermole wrote:
 On 14/03/2018 1:02 AM, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 11:31:12 UTC, rikki cattermole 
 wrote:
 Ah yes.
 You're completely correct if you subscribe to Adam's and 
 ketmar's file sizes expectation.

 A D module and package is one level of abstraction. If that 
 level of abstraction starts to fill up and gets large, you 
 split it up.

 My rule is soft 1k LOC and hard 2-3k (after that it needs a 
 VERY good reason to stay together).

 This makes each file to be very right down to the point and 
 do nothing else.

 You should be doing this no matter the language IMO. Just the 
 difference is in Java only one class is publicly accessible 
 per file. Nothing stops you from doing that here either.
Fair enough. I doubt I'll use your 'lines of code' method as a means of encapsulation though ;-)
The number of lines of code is more of a code smell which suggests that the module is going out of scope in size and functionality.
 I have to think more, about what a module is really trying to 
 encapsulate.
 
 I'm sure there is a good blog that could come out of this 
 conversation.
 (not by me though)
While it is new to some people, we would only be rehashing existing ideas that have existed in the literature for 40+ years.
Mmm...I think more than just 'some people' will be suprised when they come to D, and suddenly find that a private member may not be private at all. vast majority of programmers on the planet. private string _Name; (oh..in D, this might be private..or it might not be..depends on what you mean by private)
Mar 13 2018
prev sibling next sibling parent aliak <something something.com> writes:
On Tuesday, 13 March 2018 at 06:58:08 UTC, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:
 The same applies here. Encapsulation simply isn't broken by 
 this feature.
What you're saying, is in D, class encapsulation is really 'module' encapsulation. I get it. Fine. It's an intersting design decision. But, in doing that, D has shifted the boundary of class encapsulation, to a boundary that is outside the class. To me, that sounds like D has broken class encapsulation. I don't know how else one could describe it. I continue to think, that class encapsulation is sacred, a well defined, well understood, concept that has been around for a very long time. private could have still meant private, and surely someone could have come up with a different access modifier to mean 'private at module level'. Was that too hard the language designers? Was it not hard, but just to complex to implement? I don't get it.
I agree that class encapsulation is broken, well, not broken but just not a thing really. Don't think it's a bad thing though. Case in point, swift had private as file level access, swift 3 they introduced fileprivate [0] to do that instead and had private be scope level (which includes class level and is what you're referring to private being). Swift 4 they reverted it .... kinda [1] It was too inconvenient to not allow access to private members within a file in a language that allows extensions (think ufcs). So they compromised a bit here and went for decleration level which makes sense within their extension semantics. This would not work for D thought because ufcs is not really a type extension (i.e. not part of a type's typeinfo) So now the difference is that private can be used in a file but only in a declaration and fileprivate can be used anywhere in a file. So they allow class encapsulation but at a file level. It's an interesting approach and quite neat. Rust is also the same as D I believe. Module is the unit of encapsulation. I wouldn't want private to change it's meaning quite frankly in the module system. I would not mind more control within a module though because, well, encapsulation. A Rust-ish approach were you can define a path [2] might allow for a lot more freedom but I'm not sure how well that would work with D. Cheers [0] https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md [1] https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md [2] https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html
Mar 13 2018
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 13 March 2018 at 06:58:08 UTC, psychoticRabbit wrote:

 What you're saying, is in D, class encapsulation is really 
 'module' encapsulation.

 I get it. Fine. It's an intersting design decision.
"Enapsulation" in D means the same as it does in every other language -- hidden from the outside. The purpose of encapsulation is to prevent client code from breaking when an internal API changes. That's exactly the level of encapsulation that D's private provides. Making private restrict access to the class would be like other languages, sure, but then it becomes over restrictive.
 But, in doing that, D has shifted the boundary of class 
 encapsulation, to a boundary that is outside the class.
Nope. It's still hidden from the outside world. No one can read or write private class members *from the external API*.
 To me, that sounds like D has broken class encapsulation. I 
 don't know how else one could describe it.

 I continue to think, that class encapsulation is sacred, a well 
 defined, well understood, concept that has been around for a 
 very long time.
Only if you view encapsulation as something other than "hidden from the outside world".
 private could have still meant private, and surely someone 
 could have come up with a different access modifier to mean 
 'private at module level'.

 Was that too hard the language designers?

 Was it not hard, but just to complex to implement?

 I don't get it.
Any new keywords, or reuse of existing keywords, does make the language more complex. Everything that is added must have a reason. Private is module level because friend is so common in C++, i.e. people find it useful and it would be great to support something similar in D. Making modules the lowest level of encapsulation does that without the need for an extra keyword for friends while still maintaining a strict border between external and internal APIs. Moreover, it restricts friends to the same module, easing the maintenance burden and decreasing the chance of error. It was a great decision.
Mar 13 2018
next sibling parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 08:44:48 UTC, Mike Parker wrote:
 Any new keywords, or reuse of existing keywords, does make the 
 language more complex. Everything that is added must have a 
 reason. Private is module level because friend is so common in 
 C++, i.e. people find it useful and it would be great to 
 support something similar in D. Making modules the lowest level 
 of encapsulation does that without the need for an extra 
 keyword for friends while still maintaining a strict border 
 between external and internal APIs. Moreover, it restricts 
 friends to the same module, easing the maintenance burden and 
 decreasing the chance of error. It was a great decision.
yeah, I probably agree that it's a good decision, when the module is the boundary. (aka so-called 'principled' violation of encapsulation) what I don't like, is that I have no way at all to protect members of my class, from things in the module, without moving that class out of that module. D wants me to completely trust the module, no matter what. That's make a little uncomfortable, given how long and complex modules can easily become(and aleady are)
Mar 13 2018
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 13 March 2018 at 09:14:26 UTC, psychoticRabbit wrote:

 That's make a little uncomfortable, given how long and complex 
 modules can easily become(and aleady are)
Is there a practical difference between a) a module that contains a class with 20 member functions all accessing private members of the class and b) a module that contains a class with two member functions and 18 free functions all accessing private members of the class? Does it really make a difference that some functions are on one side of a closing brace and some on the other?
Mar 13 2018
parent psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 09:52:06 UTC, Mike Parker wrote:
 On Tuesday, 13 March 2018 at 09:14:26 UTC, psychoticRabbit 
 wrote:

 That's make a little uncomfortable, given how long and complex 
 modules can easily become(and aleady are)
Is there a practical difference between a) a module that contains a class with 20 member functions all accessing private members of the class and b) a module that contains a class with two member functions and 18 free functions all accessing private members of the class? Does it really make a difference that some functions are on one side of a closing brace and some on the other?
The scenario you mentioned is fine, as long as I don't want to protect any of my class members from free functions within the module. When I do decide that something in my class really does need protection, I have to move the class outside of the module. This concept is new to me. I have to keep thinking about it. To lose control at the level of class encapsulation, and surrender it completely to the module, no matter what..well..I'm a little unsure about it. I'd be more comfortable with being able to have your scenario and mine 'both work'. At what point, does 'principled' violation of encapsulation, just become a violation of encapsulation?
Mar 13 2018
prev sibling parent Nathan S. <no.public.email example.com> writes:
On Tuesday, 13 March 2018 at 09:14:26 UTC, psychoticRabbit wrote:
 what I don't like, is that I have no way at all to protect 
 members of my class, from things in the module, without moving 
 that class out of that module.

 D wants me to completely trust the module, no matter what.

 That's make a little uncomfortable, given how long and complex 
 modules can easily become(and aleady are)
I used to feel similarly and understand where you're coming from but after using D for a while the old way feels ridiculous and cumbersome to me. The problem of accidents even in large files can be avoided by using names like "m_length" or "_length": no jury in the world will believe you if you write those then say you didn't know they were private.
Mar 13 2018
prev sibling next sibling parent psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 08:44:48 UTC, Mike Parker wrote:
 Moreover, it restricts friends to the same module, easing the 
 maintenance burden and decreasing the chance of error. It was a 
 great decision.
But, a module can contain so many 'friends'. Q. How many 'friends' does it take, before you lose the capacity to reason about who really is a friend?
Mar 13 2018
prev sibling parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 08:44:48 UTC, Mike Parker wrote:
 Making modules the lowest level of encapsulation does that 
 without the need for an extra keyword for friends while still 
 maintaining a strict border between external and internal APIs. 
 Moreover, it restricts friends to the same module, easing the 
 maintenance burden and decreasing the chance of error. It was a 
 great decision.
Actually I wonder if it's the opposite of that, because now, if I have a bug in my class implementation, the code is no longer localised to the class, but to the module - this greatly increases the burden of program correctness and maintenance. It also means the author of the class is no longer free to make changes, because all the surrounding code in the module needs to be assessed for impact - this greatly increases the burden of program correctness and maintenance.
Mar 13 2018
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 13 March 2018 at 13:08:44 UTC, psychoticRabbit wrote:
 It also means the author of the class is no longer free to make 
 changes, because all the surrounding code in the module needs 
 to be assessed for impact - this greatly increases the burden 
 of program correctness and maintenance.
The author of the class could just put it in a separate file. As If you can't put it in a separate file, it isn't as encapsulated as you think anyway!
Mar 13 2018
prev sibling next sibling parent reply psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:
 I think it's a great feature and I use it frequently. It's 
 allows more flexibility in class design. Without it, we'd need 
 another protection attribute to enable the concept of "private 
 to the module".
what about a new access attribute (and no, I haven't though this through much): owned string _FirstName; (now the class 'owns' this. It is neither readable nor writeable outside the boundary of that class. This retains the existing flexibilty offered by module level encapsulation, while restoring class level encapsulation/ownership.
Mar 13 2018
next sibling parent Radu <void null.pt> writes:
On Tuesday, 13 March 2018 at 08:05:43 UTC, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:
 I think it's a great feature and I use it frequently. It's 
 allows more flexibility in class design. Without it, we'd need 
 another protection attribute to enable the concept of "private 
 to the module".
what about a new access attribute (and no, I haven't though this through much): owned string _FirstName; (now the class 'owns' this. It is neither readable nor writeable outside the boundary of that class. This retains the existing flexibilty offered by module level encapsulation, while restoring class level encapsulation/ownership.
So, what's wrong with this? =================================== module foo; class Blah { public int pub; private int priv; } =================================== module bar; import foo; void main() { auto c = new Blah(); c.priv = 42; // compile error } =================================== You can still code like Java, one file per class (module) and keep those private members protection across modules classes. What's different with D is that the scope is the module not the class (package), and this is good. This is a trade-of, usually one codes related components in a module, thus frequently needs access to those components inside the module. You can have class, struct, functions, enums, static variables and templates in the same module, and pragmatically you will need to access private data on them. You still have the private to signal the intent, just that the philosophy is different when looking at the basic compilation unit.
Mar 13 2018
prev sibling parent psychoticRabbit <meagain meagain.com> writes:
On Tuesday, 13 March 2018 at 08:05:43 UTC, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:
 I think it's a great feature and I use it frequently. It's 
 allows more flexibility in class design. Without it, we'd need 
 another protection attribute to enable the concept of "private 
 to the module".
what about a new access attribute (and no, I haven't though this through much): owned string _FirstName; (now the class 'owns' this. It is neither readable nor writeable outside the boundary of that class. This retains the existing flexibilty offered by module level encapsulation, while restoring class level encapsulation/ownership.
or another idea: ownedBy T string _FirstName; where T could be 'Module' (meaning it works the way it currently does. The module can read/write to it). or T could 'Universe' (where universe means everyone can do whatever they want with it). or T could be 'This'(so class can regain control overs its own members), The default could be ownedBy Module, to retain existing behaviour. I'd even go further, with extended attributes... ownedBy Module Read string _FirstName; ownedBy Module Write string _FirstName; ownedBy Module ReadWrite string _FirstName;
Mar 13 2018
prev sibling parent reply Tony <tonytdominguez aol.com> writes:
On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:



Java has four protection levels. If you don't explicitly specify [private, protected, public] the protection level is implicitly "package-private". That means that any class in the same package can access that attribute. I believe that Java packages are identical to D packages.
Mar 18 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, March 18, 2018 18:04:13 Tony via Digitalmars-d-learn wrote:
 On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:


Java has four protection levels. If you don't explicitly specify [private, protected, public] the protection level is implicitly "package-private". That means that any class in the same package can access that attribute. I believe that Java packages are identical to D packages.
They're similar, but there are differences. For instance, you can do package(a) in D in order to do something like put the stuff in a.b.c in package a rather than a.b. Also, package functions in D are never virtual, which I expect is not the case for Java. The whole situation is also complicated somewhat by the fact that D allows pretty much anything at module-level, whereas as Java requires one class per module, though I'm not sure that that has much direct effect on package itself other than the fact that it's possible in D to mark stuff package that isn't in a class. - Jonathan M Davis
Mar 18 2018
parent reply Tony <tonytdominguez aol.com> writes:
On Sunday, 18 March 2018 at 18:32:42 UTC, Jonathan M Davis wrote:

 They're similar, but there are differences. For instance, you 
 can do package(a) in D in order to do something like put the 
 stuff in a.b.c in package a rather than a.b.
Is there a known situation where it makes sense to put module c in directory/package b - rather than directory/package a, and then tell the D compiler to treat it like it was in directory/package a?
Mar 18 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, March 18, 2018 18:59:39 Tony via Digitalmars-d-learn wrote:
 On Sunday, 18 March 2018 at 18:32:42 UTC, Jonathan M Davis wrote:
 They're similar, but there are differences. For instance, you
 can do package(a) in D in order to do something like put the
 stuff in a.b.c in package a rather than a.b.
Is there a known situation where it makes sense to put module c in directory/package b - rather than directory/package a, and then tell the D compiler to treat it like it was in directory/package a?
I don't think that you can have anything in a/b/c.d marked as if it were in package a/z. It's only for putting stuff higher up in the package hierarchy while allowing it to be placed in modules deeper in the hierarchy, not for moving it laterally within the package hierarchy. One place where it's used (and which IIRC was the motivating reason for its implementation) is std.internal.* in Phobos. At least some of what's there is marked with package(std) (and probably all of it should be, but a lot of it predates the improvement to package). That way, stuff that's essentially private to Phobos can be organized there but be used by anything in Phobos, whereas without the improvement to package, they'd all have to be modules directly under std (probably all with internal in their module names) in order to have them being treated as being in the std package. So, ultimately, it's about better organization and probably is something that only makes sense for when entire modules are essentially private to a library and not for modules that mix public and package symbols. - Jonathan M Davis
Mar 18 2018
prev sibling parent Tony <tonytdominguez aol.com> writes:
On Sunday, 18 March 2018 at 18:04:13 UTC, Tony wrote:
 On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:



Java has four protection levels. If you don't explicitly specify [private, protected, public] the protection level is implicitly "package-private". That means that any class in the same package can access that attribute. I believe that Java packages are identical to D packages.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/accessibility-levels public - Access is not restricted. protected - Access is limited to the containing class or types derived from the containing class. private - Access is limited to the containing type. internal - Access is limited to the current assembly. protected internal - Access is limited to the current assembly or types derived from the containing class. private protected - Access is limited to the containing class or types derived from the containing class within the current "An assembly is a "unit of deployment" for .NET, almost always a .exe or .dll. And also refers to https://social.msdn.microsoft.com/Forums/en-US/088ce8ed-ef9b-4dea-88b3-ca016885e26d/what-is-an-assembly-in-terms-of-c?forum=csharplanguage which says: "Assemblies are the building blocks of .NET Framework applications; they form the fundamental unit of deployment, version control, reuse, activation scoping, and security permissions. An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. An assembly provides the common language runtime with the information it needs to be aware of type implementations. To the runtime, a type does not exist outside the context of an assembly."
Mar 18 2018
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Tuesday, 13 March 2018 at 05:11:48 UTC, psychoticRabbit wrote:
 If you have access to the module source, you have access to 
 the source of types inside it. Making the module the lowest 
 level of encapsulation makes sense from that perspective.
There are two problems I see: 1st - D has broken the concept of class encapsulation, simply for convenience at the module level. Not good in my opinion.
It's a language design decision as to whether a particular feature is worth supporting. I would like this feature too though. I'm not sure how much compiler complexity would be added by having another visibility modifier. I'm surprised how many people here ignore the advantage of being able to modify your class/struct fields without the chance of breaking template code that might not even be instantiated by a unit test. (And no, the answer to this isn't fix your tests, because if that's your attitude, why bother with static typing, just use duck typing, the unit tests will catch any bugs). In theory this and other generic unit test issues could be comprehensively solved by having a Rust-like traits feature.

 syntax, but get very different semantics. Not good in my 
 opinion. (i.e. I only realised private was not private, by 
 accident).

 D has made many good design decisions. I do not see this as one 
 of them.
+1, D should have used a different keyword, such as `module`. It is a classic source of confusion for programmers familiar with many statically typed languages, and it comes up regularly here. It is a syntax issue, semantically the feature is better than just having true private.
Mar 17 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Saturday, 17 March 2018 at 09:18:13 UTC, Nick Treleaven wrote:
 It's a language design decision as to whether a particular 
 feature is worth supporting. I would like this feature too 
 though. I'm not sure how much compiler complexity would be 
 added by having another visibility modifier.
D could add an new attribute to class members: deny A deny attribute can come before a classes private member, to indicate that the private member is to remain private, even within the module. Cause sure, it nice to be among friends, but you don't want your friends knowing every thought that is going through your mind! Sometimes, somethings, just need to remain private. deny private string _userName; now... _userName is no longer accessible at the module level, and class encapsulation is restored. If had I any clue about compilers, I'd think this through more ;-)
Mar 17 2018
parent reply bauss <jj_1337 live.dk> writes:
On Saturday, 17 March 2018 at 11:08:27 UTC, psychoticRabbit wrote:
 On Saturday, 17 March 2018 at 09:18:13 UTC, Nick Treleaven 
 wrote:
 It's a language design decision as to whether a particular 
 feature is worth supporting. I would like this feature too 
 though. I'm not sure how much compiler complexity would be 
 added by having another visibility modifier.
D could add an new attribute to class members: deny A deny attribute can come before a classes private member, to indicate that the private member is to remain private, even within the module. Cause sure, it nice to be among friends, but you don't want your friends knowing every thought that is going through your mind! Sometimes, somethings, just need to remain private. deny private string _userName; now... _userName is no longer accessible at the module level, and class encapsulation is restored. If had I any clue about compilers, I'd think this through more ;-)
I don't like the name deny, personally I would rather see the private attribute changed to something like: private(true) // The member is oly visible to its parent. private(false) // Same as just "private", visible to whole module. Could be specialized to something like: private(this) // Same as private(true) private(module) // Same as private(false) That way it can be introduced without breaking changes and looks cleaner since it wouldn't be yet another attribute. Really it's just an extension to the already existing attribute. This feature should be relatively easy to implement since it's similar to the "package" attribute, which also takes a value as the module name.
Mar 17 2018
next sibling parent reply psychoticRabbit <meagain meagain.com> writes:
On Saturday, 17 March 2018 at 14:16:19 UTC, bauss wrote:
 I don't like the name  deny .....
how about: reallyis private string firstName_; mmm..perhaps not... then how about... strictly private string firstName_;
Mar 17 2018
parent bauss <jj_1337 live.dk> writes:
On Saturday, 17 March 2018 at 15:02:21 UTC, psychoticRabbit wrote:
 On Saturday, 17 March 2018 at 14:16:19 UTC, bauss wrote:
 I don't like the name  deny .....
how about: reallyis private string firstName_; mmm..perhaps not... then how about... strictly private string firstName_;
Still introduces a new attribute. D already has a lot of attributes and it goes against how every other attribute for visibility works. That's why my suggestion would work better, because the package attribute already works like that.
Mar 17 2018
prev sibling parent reply arturg <var.spool.mail700 gmail.com> writes:
On Saturday, 17 March 2018 at 14:16:19 UTC, bauss wrote:
 I don't like the name  deny, personally I would rather see the 
 private attribute changed to something like:

 private(true) // The member is oly visible to its parent.

 private(false) // Same as just "private", visible to whole 
 module.

 Could be specialized to something like:

 private(this) // Same as private(true)

 private(module) // Same as private(false)
maybe extend that to a list of types? private(typeof(this), Foo, Bar) would mean only typeof(this), Foo and Bar from the same module have access.
Mar 17 2018
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 17 March 2018 at 21:22:44 UTC, arturg wrote:
 maybe extend that to a list of types?
this is basically what C++ friend does and D was trying to avoid the complexity of
Mar 17 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Saturday, 17 March 2018 at 21:33:01 UTC, Adam D. Ruppe wrote:
 On Saturday, 17 March 2018 at 21:22:44 UTC, arturg wrote:
 maybe extend that to a list of types?
this is basically what C++ friend does and D was trying to avoid the complexity of
Really, the complexity of 'friend' comes from people abusing it. In D, I would prefer no breaking change here. Leave private as it is. Just a simple attribute that only applies within a class, and only to private members within that class. strictly private string firstName_; Nothing outside of the class, not even the module, can access this now. It's all encapsulated. It breaks nothing (AFAIK). It's very clear what the intention is here. It's an easy attribute to remember. It restores the principle of class enscapsulation within a module, for when it's really needed. Now D programmers would have the best of both worlds.
Mar 17 2018
next sibling parent bauss <jj_1337 live.dk> writes:
On Saturday, 17 March 2018 at 23:54:22 UTC, psychoticRabbit wrote:
 In D, I would prefer no breaking change here. Leave private as 
 it is.
My suggestion has no breaking change and it works just like the package attribute already works. Also you shouldn't allow multiple types for it, that would defeat the purpose of private again and in that case you should just use as is, since module-level private can already ensure that. If you need to share it with types outside of the module, then it's pointless, because you're essentially just duck-taping an issue of your program design and not the language design.
Mar 18 2018
prev sibling next sibling parent reply psychoticRabbit <meagain meagain.com> writes:
On Sunday, 18 March 2018 at 05:01:39 UTC, Amorphorious wrote:
 The fact is, the creator of the class is also the creator of 
 the module.. and preventing him from having full access to the 
 class is ignorant. He doesn't need to encapsulate himself. 
 Encapsulation is ONLY meant to reduce dependencies. If the 
 programmer, probably someone like you, can't trust himself to 
 understand his own code then he shouldn't be coding.
btw. I am talking here about 'encapsulation' not 'information hiding' (although the two terms are often considered related). Clearly, there is no point in hiding information contained within the module, from the implementer of the module. That's just silly. However, are there no scenarios in which the person writing that module, would not want to encapsulate their class, or some parts of it, from the rest of the module (while not being forced to put the class in it's own file)? If the answer is certainly no, not under any circumstances, then fine, my idea is not worth any further consideration. And by no, I mean no for all, not just you.
Mar 18 2018
parent reply Alex <sascha.orlov gmail.com> writes:
On Sunday, 18 March 2018 at 09:56:31 UTC, psychoticRabbit wrote:
 However, are there no scenarios in which the person writing 
 that module, would not want to encapsulate their class, or some 
 parts of it, from the rest of the module (while not being 
 forced to put the class in it's own file)?

 If the answer is certainly no, not under any circumstances, 
 then fine, my idea is not worth any further consideration.

 And by no, I mean no for all, not just you.
I assume, that the following statement is equivalent to yours: ´´´ Are there any scenarios in which the person writing the class, would want to encapsulate their class, or some parts of it, from the rest of a module (while being forced to put the class in this module)? ´´´ The answer is no. As the person which is writing the class has always the power to decide which module to edit to put the class in. And due this fact, the statement
 The fact is, the creator of the class is also the creator of 
 the module..
is the coolest semantic statement of the whole thread so far, I think :)
Mar 18 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Sunday, 18 March 2018 at 11:12:46 UTC, Alex wrote:
 ´´´
 Are there any scenarios in which the person writing the class, 
 would want to encapsulate their class, or some parts of it, 
 from the rest of a module (while being forced to put the class 
 in this module)?
 ´´´

 The answer is no. As the person which is writing the class has 
 always the power to decide which module to edit to put the 
 class in.

 And due this fact, the statement

 The fact is, the creator of the class is also the creator of 
 the module..
is the coolest semantic statement of the whole thread so far, I think :)
Well, it seems to me, that the only real objection one can have to improving encapsulation within a module, is objecting to improving encapsulation within a module. The fact that the creator of a class, is also the creator of the module that contains that class, is not a valid reason for not seeking to improve encapsulation of that class.
Mar 18 2018
parent bauss <jj_1337 live.dk> writes:
On Monday, 19 March 2018 at 01:11:43 UTC, psychoticRabbit wrote:
 The fact that the creator of a class, is also the creator of 
 the module that contains that class, is not a valid reason for 
 not seeking to improve encapsulation of that class.
I agree with this. This especially matters with projects where multiple people might work on the same module. You might not want to expose every member to all the people who work on the module. Whereas you might want other members to be exposed to the module and not outside, so the argument for putting the class into a new module doesn't work either, since the members you do want to expose cannot be exposed, unless they're public, in which case it defeats the whole purpose of encapsulation. Yes, it's great that private is module-level by default, but it just doesn't work in practice with modules worked on by multiple people. Tons of bugs can be avoided too, like a few times unittests have passed in phobos with traits because private members were visible in the module. (I can't remember a specific example on top of my head, but it has happened a few times.)
Mar 19 2018
prev sibling parent reply Alain Soap <asap soon.hu> writes:
On Saturday, 17 March 2018 at 23:54:22 UTC, psychoticRabbit wrote:
 On Saturday, 17 March 2018 at 21:33:01 UTC, Adam D. Ruppe wrote:
 On Saturday, 17 March 2018 at 21:22:44 UTC, arturg wrote:
 maybe extend that to a list of types?
this is basically what C++ friend does and D was trying to avoid the complexity of
Really, the complexity of 'friend' comes from people abusing it. In D, I would prefer no breaking change here. Leave private as it is. Just a simple attribute that only applies within a class, and only to private members within that class. strictly private string firstName_; Nothing outside of the class, not even the module, can access this now. It's all encapsulated. It breaks nothing (AFAIK). It's very clear what the intention is here. It's an easy attribute to remember. It restores the principle of class enscapsulation within a module, for when it's really needed. Now D programmers would have the best of both worlds.
Yesterday i thought to reuse `super`: struct Foo { super private: int _stats; int _field; public: int field(){_stats++; return _field;} void field(int value){_stats++; _field = value;} } BTW i think adding this can be useful. The FreePascal language has `strict private` for example.
Mar 18 2018
parent reply psychoticRabbit <meagain meagain.com> writes:
On Sunday, 18 March 2018 at 10:14:30 UTC, Alain Soap wrote:
 BTW i think adding this can be useful. The FreePascal language 
 has `strict private` for example.
" Private - All fields and methods that are in a private block, can only be accessed in the module (i.e. unit) that contains the class definition. They can be accessed from inside the classes’ methods or from outside them (e.g. from other classes’ methods)" " Strict Private - All fields and methods that are in a strict private block, can only be accessed from methods of the class itself. Other classes or descendent classes (even in the same unit) cannot access strict private members. " https://www.freepascal.org/docs-html/ref/refse34.html interesting...someone else clearly had the idea. hey..perhaps I'm not a moron after all.
Mar 18 2018
parent Alain Soap <asap soon.hu> writes:
On Sunday, 18 March 2018 at 10:45:55 UTC, psychoticRabbit wrote:
 On Sunday, 18 March 2018 at 10:14:30 UTC, Alain Soap wrote:
 [...]
" Private - All fields and methods that are in a private block, can only be accessed in the module (i.e. unit) that contains the class definition. They can be accessed from inside the classes’ methods or from outside them (e.g. from other classes’ methods)" " Strict Private - All fields and methods that are in a strict private block, can only be accessed from methods of the class itself. Other classes or descendent classes (even in the same unit) cannot access strict private members. " https://www.freepascal.org/docs-html/ref/refse34.html interesting...someone else clearly had the idea. hey..perhaps I'm not a moron after all.
Change your pseudo.
Mar 18 2018
prev sibling next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
psychoticRabbit wrote:

 On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote:
 private is private to the module, not the class. There is no way in D to 
 restrict the rest of the module from accessing the members of a class. 
 This simplification makes it so that stuff like C++'s friend are 
 unnecessary. If your class in a separate module from main, then main 
 won't be able to access its private members.

 - Jonathan M Davis
Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all.
just stop thinking in C/C++ "#include" terms. there, you have no other ways to restrict data access, so they were forced to make it broken, and then introduce "friends" just to workaround the fact that there are no modules in C++. instead, start thinking with modules in mind. module is THE unit of incapsulation. there is nothing wrong in isolating class or two in a module. then, to make imports manageable, either create a package of that, or just a dummy module that does `public import xxx;` for everything.
Mar 12 2018
prev sibling next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, March 13, 2018 02:06:57 psychoticRabbit via Digitalmars-d-learn 
wrote:
 On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote:
 private is private to the module, not the class. There is no
 way in D to restrict the rest of the module from accessing the
 members of a class. This simplification makes it so that stuff
 like C++'s friend are unnecessary. If your class in a separate
 module from main, then main won't be able to access its private
 members.

 - Jonathan M Davis
Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all.
Well, this thread sure blew up fast... The decision to make private restrict access to the module certainly has pros and cons, but it works well over all. C++'s solution using friend is more flexible, but it's also more complicated. D's solution removes that extra complication. It also makes the use of private throughout the module more consistent, since unlike C++, D has modules and has to worry about the access level of symbols within a module and not just within classes. Also, given D's built-in unit testing features, being able to have unittest blocks within the module access anything within the module makes testing much easier. No one has to muck with access levels to make stuff available to unit tests as is often the case with languages like Java. And while it might initially seem annoying that you can't restrict access of a member to a class or struct even within a module, it's something that most of us have found to not be a problem in practice. But as with all design decisions, there are tradeoffs, and different people have different opinions about which tradeoffs make the most sense. The only case I'm aware of where I'd consider the current design to be a problem is that if all of your testing is done within the module, it's harder to catch cases where you screwed up the access level and made something private when you didn't mean to. Being able to access all of the private stuff for tests can be extremely useful, so it's certainly not the case that simply making it so that unittest blocks had only public or package access would be a clear improvement, but it's also not the case that the current design doesn't come with any downsides. If you really want to restrict access to the class itself, then you can always just declare a class in its own module just like Java forces you to do. That might be annoying if want to put several classes in the same module while restricting their access, but it is a way to enforce full encapsulation if that's what you really want. Ultimately though, for better or worse, D considers the module to be the primary unit of encapsulation in the language, and most of us find that it works quite well. Given time you may find that you don't mind it as much - or not, but that's the way that D does it, and I very much doubt that that's ever going to change. - Jonathan M Davis
Mar 13 2018
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 3/12/18 10:06 PM, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote:
 private is private to the module, not the class. There is no way in D 
 to restrict the rest of the module from accessing the members of a 
 class. This simplification makes it so that stuff like C++'s friend 
 are unnecessary. If your class in a separate module from main, then 
 main won't be able to access its private members.

 - Jonathan M Davis
Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all.
OK, so I agree there are drawbacks. But these can be worked around. In fact, the language author touted this article as sage advice, when in D it's pretty inconvenient: https://forum.dlang.org/post/osr2l3$1ihb$2 digitalmars.com But when you get right down to it, where you draw the line is arbitrary. Given the power to encapsulate on module boundary, you have lots of different options as to where your functions can reach. You can pretty much put anything into a module, so you aren't limited to class members which can access specific data. With the advent of package modules, you can control quite finely what functions have access to what items, and still have nice simple imports. If you limit to class members, then you have to do something like C++ friends, which are unnecessarily verbose. IMO, the module-level encapsulation is the right choice. It helps with a lot of key features: 1. IFTI factory methods 2. unittests 3. co-related structs/classes -Steve
Mar 13 2018
next sibling parent reply Arun Chandrasekaran <aruncxy gmail.com> writes:
On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer 
wrote:
 On 3/12/18 10:06 PM, psychoticRabbit wrote:
 [...]
OK, so I agree there are drawbacks. But these can be worked around. [...]
Private members still have external linkage. Is there anyway to solve this?
Mar 13 2018
next sibling parent reply Nathan S. <no.public.email example.com> writes:
On Tuesday, 13 March 2018 at 21:36:13 UTC, Arun Chandrasekaran 
wrote:
 On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer 
 wrote:
 On 3/12/18 10:06 PM, psychoticRabbit wrote:
 [...]
OK, so I agree there are drawbacks. But these can be worked around. [...]
Private members still have external linkage. Is there anyway to solve this?
Yeah that's a real WTF.
Mar 13 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, March 13, 2018 22:25:52 Nathan S. via Digitalmars-d-learn wrote:
 On Tuesday, 13 March 2018 at 21:36:13 UTC, Arun Chandrasekaran

 wrote:
 On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer

 wrote:
 On 3/12/18 10:06 PM, psychoticRabbit wrote:
 [...]
OK, so I agree there are drawbacks. But these can be worked around. [...]
Private members still have external linkage. Is there anyway to solve this?
Yeah that's a real WTF.
It's how linking is normally done on Linux with C/C++ and has the advantage of not having to mark any functions as being external like you have to do on Windows. Personally, I've always found having to deal with that with C/C++ on Windows to be extremely annoying, whereas on Linux, shared libraries just work. So, from a usability perspective, I can't say that I'm at all pleased at the idea of having to mark anything as having external linkage in D. The downside is that it increases the number of symbols which the program has to deal with when linking against a shared library, which can have some negative effects. - Jonathan M Davis
Mar 13 2018
parent Nathan S. <no.public.email example.com> writes:
On Tuesday, 13 March 2018 at 22:56:31 UTC, Jonathan M Davis wrote:
 The downside is that it increases the number of symbols which 
 the program has to deal with when linking against a shared 
 library, which can have some negative effects.

 - Jonathan M Davis
If I understand correctly it's also responsible for TypeInfo being generated for private classes regardless of whether or not it is ever used.
Mar 15 2018
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, March 13, 2018 21:36:13 Arun Chandrasekaran via Digitalmars-d-
learn wrote:
 On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer

 wrote:
 On 3/12/18 10:06 PM, psychoticRabbit wrote:
 [...]
OK, so I agree there are drawbacks. But these can be worked around. [...]
Private members still have external linkage. Is there anyway to solve this?
No. There are some folks who want to change it so that you have to use extern to have external linkage, but all of that is a work in progress and would have to be approved by Walter. - Jonathan M Davis
Mar 13 2018
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer 
wrote:
 If you limit to class members, then you have to do something 
 like C++ friends, which are unnecessarily verbose.
Not if you also have a module-level visibility modifier, which could have been `module`.
 IMO, the module-level encapsulation is the right choice. It 
 helps with a lot of key features:

 1. IFTI factory methods
Aren't these mainly because constructors can't use IFTI, unlike C++17, and because nullary struct constructors are banned?
 2. unittests
Documented unittests should not be allowed to use private symbols, I just filed this: https://issues.dlang.org/show_bug.cgi?id=18623
Mar 17 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 3/17/18 5:56 AM, Nick Treleaven wrote:
 On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer wrote:
 If you limit to class members, then you have to do something like C++ 
 friends, which are unnecessarily verbose.
Not if you also have a module-level visibility modifier, which could have been `module`.
If we could go back in time and talk with a young Walter about the consequences of choosing the scheme the way it is, maybe he might have made different choices, but at this point, it's hard to change it. Note, again, you can do pretty much every privacy scheme you want with package modules today. Before, it was a lot less nice. It's pretty simple: all your friends go into the module. All your external functions that should only use the public API have to go elsewhere. I think the thing that bites people is simply that they aren't used to it.
 
 IMO, the module-level encapsulation is the right choice. It helps with 
 a lot of key features:

 1. IFTI factory methods
Aren't these mainly because constructors can't use IFTI, unlike C++17,
While this is a limitation that I wish wasn't there, constructors aren't always the best way to build a type. But there are other reasons to put functions that access private pieces outside the aggregate. For instance, if you want to accept a struct by value.
 
 2. unittests
Documented unittests should not be allowed to use private symbols, I just filed this: https://issues.dlang.org/show_bug.cgi?id=18623
Why not? unittest { auto foo = new Foo; assert(foo.internalbuffer.empty); // note, this is a private symbol. } I can do the same thing in ddoc, but without the benefit of having the unit test run. Forcing me to do it that way is just annoying (I will have to duplicate the code). -Steve
Mar 18 2018
next sibling parent psychoticRabbit <meagain meagain.com> writes:
On Sunday, 18 March 2018 at 18:45:23 UTC, Steven Schveighoffer 
wrote:
 If we could go back in time and talk with a young Walter about 
 the consequences of choosing the scheme the way it is, maybe he 
 might have made different choices, but at this point, it's hard 
 to change it.
I think this highlights the real problem with D. Power is too centralised, and kinda arbitrary. I'm going back to Java ;-)
Mar 18 2018
prev sibling parent Nick Treleaven <nick geany.org> writes:
On Sunday, 18 March 2018 at 18:45:23 UTC, Steven Schveighoffer 
wrote:
 unittest
 {
    auto foo = new Foo;
    assert(foo.internalbuffer.empty); // note, this is a private 
 symbol.
 }
I don't understand why you would want a private symbol in a *documented* unittest, the reader of the *documentation* will not be able to run the example code.
 I can do the same thing in ddoc, but without the benefit of 
 having the unit test run.
You mean not using a unittest?
 Forcing me to do it that way is just annoying (I will have to 
 duplicate the code).
If you really want your documented unittests not to be runnable by a user, you can have a free function with `protected` access as a workaround.
Mar 29 2018
prev sibling parent JN <666total wp.pl> writes:
On Tuesday, 13 March 2018 at 02:06:57 UTC, psychoticRabbit wrote:
 On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis 
 wrote:
 private is private to the module, not the class. There is no 
 way in D to restrict the rest of the module from accessing the 
 members of a class. This simplification makes it so that stuff 
 like C++'s friend are unnecessary. If your class in a separate 
 module from main, then main won't be able to access its 
 private members.

 - Jonathan M Davis
Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all.
Relevant article: http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197
Mar 13 2018