www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why do private member variables behaved like protected in the same

reply 12345swordy <alexanderheistermann gmail.com> writes:
Mike Parker told me that this is intentional and not a bug. 
However according to the spec: "Symbols with private visibility 
can only be accessed from within the same module. Private member 
functions are implicitly final and cannot be overridden."
Why private member variables behave like protected member 
variables in the same module? Can you explain your thought 
process when it comes to this design decision Walter Bright? Is 
there no way to mark the private member variables as "final" in 
the same module?

-Alex
Oct 26 2018
next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug. 
 However according to the spec: "Symbols with private visibility 
 can only be accessed from within the same module. Private 
 member functions are implicitly final and cannot be overridden."
 Why private member variables behave like protected member 
 variables in the same module? Can you explain your thought 
 process when it comes to this design decision Walter Bright? Is 
 there no way to mark the private member variables as "final" in 
 the same module?

 -Alex
*Private member variables in classes obviously -Alex
Oct 26 2018
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Why private member variables behave like protected member 
 variables in the same module?
I don't understand, what do you mean?
Oct 26 2018
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 18:40:36 UTC, Adam D. Ruppe wrote:
 On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Why private member variables behave like protected member 
 variables in the same module?
I don't understand, what do you mean?
I am referring to the class private member variable.
Oct 26 2018
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/26/18 2:16 PM, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug. However 
 according to the spec: "Symbols with private visibility can only be 
 accessed from within the same module. Private member functions are 
 implicitly final and cannot be overridden."
 Why private member variables behave like protected member variables in 
 the same module? Can you explain your thought process when it comes to 
 this design decision Walter Bright? Is there no way to mark the private 
 member variables as "final" in the same module?
There's no such thing as "final" member variables. private variables and functions are visible ONLY within the module. private *functions* are final, meaning derived types cannot override them (and they are not virtual). -Steve
Oct 26 2018
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 18:45:06 UTC, Steven Schveighoffer 
wrote:
 On 10/26/18 2:16 PM, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug. 
 However according to the spec: "Symbols with private 
 visibility can only be accessed from within the same module. 
 Private member functions are implicitly final and cannot be 
 overridden."
 Why private member variables behave like protected member 
 variables in the same module? Can you explain your thought 
 process when it comes to this design decision Walter Bright? 
 Is there no way to mark the private member variables as 
 "final" in the same module?
There's no such thing as "final" member variables.
I was referring to class member variables, not the module itself. Sorry I didn't clarify the first time. The lack of edit function makes things difficult for me.
Oct 26 2018
prev sibling next sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug.
It's not a bug.
 However according to the spec: "Symbols with private visibility 
 can only be accessed from within the same module. Private 
 member functions are implicitly final and cannot be overridden."
Why "however"? There's no contradiction. Within a module, you have access to everything.
 Why private member variables behave like protected member 
 variables in the same module?
Because according to the spec, "Symbols with private visibility can only be accessed from within the same module." It's *your* module. You already have access to it's implementation in it's entirety. There's absolutely no need for artificial restrictions. To keep your desk drawer tidy you, well, keep it tidy, not mess it up and throw away the key.
 Can you explain your thought process when it comes to this 
 design decision Walter Bright?
I'm sure Walter should be honored to be graced with such an eloquent inquiry.
 Is there no way to mark the private member variables as "final" 
 in the same module?
No.
Oct 26 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 18:45:32 UTC, Stanislav Blinov 
wrote:
 On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug.
It's not a bug.
Is this really necessarily?
 Why "however"?
Class private member variables are behaving like they protected class protected when creating derived class in the same module.
 There's no contradiction. Within a module, you have access to 
 everything.
This is about inheritance not encapsulation. You shouldn't be accessing doors when they shouldn't exist in the first place.
 Why private member variables behave like protected member 
 variables in the same module?
Because according to the spec, "Symbols with private visibility can only be accessed from within the same module."
Was referring to class member variables not the module member variables.
 It's *your* module.
There are cases where is not necessarily "my" module but rather it is the "team" module.
There's absolutely no need for
 artificial restrictions.
Nonsense, safe and nogc are artificial restrictions. Code discipline is good behavior, even for yourself.
 To keep your desk drawer tidy you, well, keep it tidy, not mess 
 it up and throw away the key.
How I organized my desk drawer is up to me though.
 Can you explain your thought process when it comes to this 
 design decision Walter Bright?
I'm sure Walter should be honored to be graced with such an eloquent inquiry.
Is that sarcasm?
Oct 26 2018
next sibling parent reply David Gileadi <gileadisNOSPM gmail.com> writes:
On 10/26/18 12:27 PM, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:45:32 UTC, Stanislav Blinov wrote:
 On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug.
It's not a bug.
Is this really necessarily?
 Why "however"?
Class private member variables are behaving like they protected class protected when creating derived class in the same module.
[snip] Whether this loophole is desirable and useful is a matter of opinion. It certainly is deliberate, though. I believe it may have been inspired by C++'s "friend" declarations. The comparison may help with understanding why D does it this way: https://dlang.org/articles/cpptod.html#friends In my opinion it reflects D's ethos of keeping the common practice safe but attempting to always allow an escape hatch.
Oct 26 2018
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 19:45:48 UTC, David Gileadi wrote:
 On 10/26/18 12:27 PM, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:45:32 UTC, Stanislav Blinov 
 wrote:
 On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug.
It's not a bug.
Is this really necessarily?
 Why "however"?
Class private member variables are behaving like they protected class protected when creating derived class in the same module.
[snip] Whether this loophole is desirable and useful is a matter of opinion.
Yes! Someone knows what I am talking about! I don't want to break other people code that depends on this loophole. I just want a way to close this loophole, by using the final keyword.
 It certainly is deliberate, though. I believe it may have been 
 inspired by C++'s "friend" declarations. The comparison may 
 help with understanding why D does it this way: 
 https://dlang.org/articles/cpptod.html#friends

 In my opinion it reflects D's ethos of keeping the common 
 practice safe but attempting to always allow an escape hatch.
If it deliberate, then it needs to be documented.
Oct 26 2018
next sibling parent reply Craig Dillabaugh <craig.dillabaugh gmail.com> writes:
On Friday, 26 October 2018 at 19:55:08 UTC, 12345swordy wrote:
 On Friday, 26 October 2018 at 19:45:48 UTC, David Gileadi wrote:
 On 10/26/18 12:27 PM, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:45:32 UTC, Stanislav Blinov 
 wrote:
 On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy 
 wrote:
 Mike Parker told me that this is intentional and not a bug.
[clip]
 Whether this loophole is desirable and useful is a matter of 
 opinion.
Yes! Someone knows what I am talking about! I don't want to break other people code that depends on this loophole. I just want a way to close this loophole, by using the final keyword.
But this loophole doesn't really provide you any mechanism to breaking other people's code that you don't already have. You write the module, and if you want to be extra safe you can follow the convention of implementing each class in its own module. [clip]
 In my opinion it reflects D's ethos of keeping the common 
 practice safe but attempting to always allow an escape hatch.
If it deliberate, then it needs to be documented.
But it is: https://dlang.org/spec/attribute.html#visibility_attributes
Oct 26 2018
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 20:22:14 UTC, Craig Dillabaugh 
wrote:

 But this loophole doesn't really provide you any mechanism to
 breaking other people's code that you don't already have.
I don't want class B to inherent class A private variables in the same module! If I want to do that I use the protected keyword in class A, that why the keyword "protected" exist in the first place! It occupied unwanted space, and creates unwanted complicity!
  You write
 the module, and if you want to be extra safe you can follow the
 convention of implementing each class in its own module.
I am not talking about encapsulation, I am talking about inheritance. To put it simply, I am not asking who can open the door or not, I am asking that if the door should exist in the first place.
 [clip]
 In my opinion it reflects D's ethos of keeping the common 
 practice safe but attempting to always allow an escape hatch.
If it deliberate, then it needs to be documented.
But it is: https://dlang.org/spec/attribute.html#visibility_attributes
If it is, then I wouldn't be having this conversation. I didn't know that derived class inherent private variables members of the parent class in the same module.
Oct 26 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, October 26, 2018 1:55:08 PM MDT 12345swordy via Digitalmars-d 
wrote:
 On Friday, 26 October 2018 at 19:45:48 UTC, David Gileadi wrote:
 It certainly is deliberate, though. I believe it may have been
 inspired by C++'s "friend" declarations. The comparison may
 help with understanding why D does it this way:
 https://dlang.org/articles/cpptod.html#friends

 In my opinion it reflects D's ethos of keeping the common
 practice safe but attempting to always allow an escape hatch.
If it deliberate, then it needs to be documented.
What are you asking for exactly? The documentation documents exactly what the behavior is: https://dlang.org/spec/attribute.html#visibility_attributes "2. Symbols with private visibility can only be accessed from within the same module. Private member functions are implicitly final and cannot be overridden." Are you looking for the documentation to explain why there is a "loophole" to private that allows other symbols within a module to access private members of a class of struct? As far as D is concerned, private doesn't even really _have_ anything to do with classes or structs. It's one of the access level attributes that you can apply to members of a class or struct (just like you can use it on module-level symbols), but it's private to the module, not the class or struct. It's understandable that you'd think that it was private to the class or struct, since other languages do that, but nowhere in the documentation does D ever say anything of the sort. It quite clearly states that it's private to the module. So, from D's perspective, there is no loophole. The whole idea that private is private to the class or struct has nothing to do with D. The only reason that you think that there's a loophole is because of preconceptions about private that you have from experience with other languages. The spec _could_ compare D's version of private to that of other languages in order to show why that particular design decision was made, but that's not the sort of thing that's usually in the spec. In general, the spec specifies what the language is but doesn't go into detail with every little decision about _why_ it is the way it is. Maybe it should in some cases. I don't know. Our spec isn't very good overall, because Walter isn't good at writing specs (and has said as much). I'd have to go study something like the C or C++ spec to see how a spec really _should_ be written. Ours can't seem to decide whether it's a tutorial or a proper spec. But what the documentation says is correct about the behavior. The whole idea that private would be anything else is just based on assumptions made after having used other languages that have private and classes. - Jonathan M Davis
Oct 26 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 20:55:00 UTC, Jonathan M Davis 
wrote:
 On Friday, October 26, 2018 1:55:08 PM MDT 12345swordy via 
 Digitalmars-d wrote:
 On Friday, 26 October 2018 at 19:45:48 UTC, David Gileadi 
 wrote:
 [...]
If it deliberate, then it needs to be documented.
What are you asking for exactly? The documentation documents exactly what the behavior is: https://dlang.org/spec/attribute.html#visibility_attributes "2. Symbols with private visibility can only be accessed from within the same module. Private member functions are implicitly final and cannot be overridden." Are you looking for the documentation to explain why there is a "loophole" to private that allows other symbols within a module to access private members of a class of struct?
No I am asking why class B inherent the private variables of class A that is marked private, when we have the protected keyword. I don't know how else I can I make this any clearer.
Oct 26 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, October 26, 2018 3:25:05 PM MDT 12345swordy via Digitalmars-d 
wrote:
 On Friday, 26 October 2018 at 20:55:00 UTC, Jonathan M Davis

 wrote:
 On Friday, October 26, 2018 1:55:08 PM MDT 12345swordy via

 Digitalmars-d wrote:
 On Friday, 26 October 2018 at 19:45:48 UTC, David Gileadi

 wrote:
 [...]
If it deliberate, then it needs to be documented.
What are you asking for exactly? The documentation documents exactly what the behavior is: https://dlang.org/spec/attribute.html#visibility_attributes "2. Symbols with private visibility can only be accessed from within the same module. Private member functions are implicitly final and cannot be overridden." Are you looking for the documentation to explain why there is a "loophole" to private that allows other symbols within a module to access private members of a class of struct?
No I am asking why class B inherent the private variables of class A that is marked private, when we have the protected keyword. I don't know how else I can I make this any clearer.
If class B is in the same module as class A, it has access to all private members of class A. It comes from the fact that private is private to the module, not private to the class. private has _nothing_ to do with inheritance. As the documentation clearly states, "symbols with private visibility can be accessed from within the same module." The idea that any derived classes in the same module would then somehow not have access comes from assumptions based on how other languages work, not from how D works or how it's documented to work. protected makes it so that derived classes - whether they be in the same module or elsewhere - can access that member. It also makes functions virtual. So, it _does_ have something to with inheritance. private, however, only has to do with modules. It has no affect on inheritance and does not make functions virtual. Similarly, package makes it so that other symbols within the same package can access that symbol. It has no effect on inheritance and does not make functions virtual. public is the only other attribute that affects inheritance or makes functions virtual, and it gives full access. Don't assume that the various access levels work the way that they do in other languages that you've used, because odds are that they don't. Aside from the fact that export needs to be better explained, they work the way that the spec describes them: https://dlang.org/spec/attribute.html#visibility_attributes Your confusion stems from the fact that you're fixating on trying to restrict access at the class level, and that is _not_ how D is designed to work. The _module_ is the base level of encapsulation that D uses. package, protected, and public all provide ways to expand access - to the package, derived classes, and everything else respectively. But the idea that you're ever restricting access to the class or struct specifically is just plain false. If you want to do that, you need to put that class or struct in a module by itself. As soon as you put it in a module with _anything_ else - including derived classes - those other symbols are going to have access to the private members of that class or struct. If you don't like that design decision, that's fine. As with almost all design decisions, there are pros and cons to it, but that doesn't mean that it has "holes" in it. It means that it defines private to mean something to have an easier time here if you stop assuming that private means the same thing in D that it means in other languages or that it's even intended to mean the same thing. You seem to keep making the mistake that visibility attributes have anything to do with restricting access at the class level in D, and they _never_ do. If you put other stuff in a module with a class, then that other stuff is going to have access to that class' members no matter what access level those members have. The visibility attributes affect which symbol outside of the module can then access those members, and in the case of member functions, it affects whether they're virtual, but it never affects whether anything else inside the module can access them. - Jonathan M Davis
Oct 26 2018
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 10/26/2018 12:45 PM, David Gileadi wrote:
 It certainly is deliberate, though.
Just to confirm, yes it is deliberate.
 I believe it may have been inspired by C++'s 
 "friend" declarations.
That is correct, as well. C++ friend is a hackish thing, with consequences in appearance, name lookup and scope. Being able to declare a "friend" that is somewhere in some other file runs against notions of encapsulation. Java's notion of one class per module is a bit too restrictive, as one may desire a set of closely interrelated classes that encapsulate a concept, and those should go into a module. C++ files tend to be accumulations of lots of stuff, often unrelated. Translations of C++ code to D (such as dmd is) reflect that as well. Phobos suffers from that, too, it's hard to break away from it. D modules should reflect a more encapsulated approach, which suggests an idiomatic D program should consist of a lot more, and smaller, modules than a typical C/C++ organization. --- I spent a lot of time learning programming in the 80's on floppy disks. Files took a long time to look up and load, so one tended to organize a program as a smaller number of larger files. Such were faster to browse and faster to compile. These effects are insignificant today, but old habits linger.
Oct 26 2018
prev sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Friday, 26 October 2018 at 19:27:11 UTC, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:45:32 UTC, Stanislav Blinov 
 wrote:
 On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug.
It's not a bug.
Is this really necessarily?
Yes. It's so that you don't solely blame Mike for your misunderstanding of the language. Now you can blame me if you want.
 Why "however"?
Class private member variables are behaving like they protected class protected when creating derived class in the same module.
Which is a problem because?..
 There's no contradiction. Within a module, you have access to 
 everything.
This is about inheritance not encapsulation. You shouldn't be accessing doors when they shouldn't exist in the first place.
So... use the language as intended and don't put things that absolutely must not access private data into the same module. Doors expunged.
 Why private member variables behave like protected member 
 variables in the same module?
Because according to the spec, "Symbols with private visibility can only be accessed from within the same module."
Was referring to class member variables not the module member variables.
Class is within a module. It's members are within a module. Ergo, they're accessible even when private. Again, there's no contradiction at all.
 It's *your* module.
There are cases where is not necessarily "my" module but rather it is the "team" module.
So? As long as the "team" uses the same language, all it's members should understand what "private" means *in that language*.
There's absolutely no need for artificial restrictions.
Nonsense, safe and nogc are artificial restrictions. Code discipline is good behavior, even for yourself.
1) safe and nogc have nothing to do with visibility. 2) Exactly my point.
 To keep your desk drawer tidy you, well, keep it tidy, not 
 mess it up and throw away the key.
 How I organized my desk drawer is up to me though.
Yep, which is exactly why the language lets you do whatever you want with symbols inside a module.
 Can you explain your thought process when it comes to this 
 design decision Walter Bright?
I'm sure Walter should be honored to be graced with such an eloquent inquiry.
Is that sarcasm?
No, no, I really think Walter owes you an explanation as to why your assumptions about the language are faulty. ...Of course it was sarcasm. Sigh.
Oct 26 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 20:52:38 UTC, Stanislav Blinov 
wrote:
 On Friday, 26 October 2018 at 19:27:11 UTC, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:45:32 UTC, Stanislav Blinov 
 wrote:
 On Friday, 26 October 2018 at 18:16:38 UTC, 12345swordy wrote:
 Mike Parker told me that this is intentional and not a bug.
It's not a bug.
Is this really necessarily?
Yes. It's so that you don't solely blame Mike for your misunderstanding of the language. Now you can blame me if you want.
What is that all about!? Are you type of guy who like get into fights?
 Why "however"?
Class private member variables are behaving like they protected class protected when creating derived class in the same module.
Which is a problem because?..
It's a problem as we have the protected keyword already! There is no reason for private to act it's protected in the same module! If you want child to inherent your private member variables then used protected. Otherwise private should mean that belongs to class A and only to class A. If you wanted your child class to inherent private member variables only in a module then we need a new access attribute to avoid unwanted pitfuls.
 There's no contradiction. Within a module, you have access to 
 everything.
This is about inheritance not encapsulation. You shouldn't be accessing doors when they shouldn't exist in the first place.
So... use the language as intended
That is a huge moot point itself that should belong it own thread.
 and don't put things that  absolutely must not access private 
 data into the  > same module.
I repeat: This is about inheritance not encapsulation. You shouldn't be accessing doors when they shouldn't exist in the first place. You are debunking a straw man.
 Class is within a module. It's members are within a module. 
 Ergo, they're accessible even when private. Again, there's no 
 contradiction at all.
Again you are debunking a straw man.
 So? As long as the "team" uses the same language, all it's 
 members should understand what "private" means *in that 
 language*.

There's absolutely no need for artificial restrictions.
Nonsense, safe and nogc are artificial restrictions. Code discipline is good behavior, even for yourself.
1) safe and nogc have nothing to do with visibility
You didn't say visibility, you said "artificial restrictions"
 To keep your desk drawer tidy you, well, keep it tidy, not 
 mess it up and throw away the key.
 How I organized my desk drawer is up to me though.
Yep, which is exactly why the language lets you do whatever you want with symbols inside a module.
Really? Then why I can't get rid private member variables that class B inherent from class A that is marked "private". Do I have to mark them delete every time I inherent?
 No, no, I really think Walter owes you an explanation as to why 
 your assumptions about the language are faulty.

 ...Of course it was sarcasm. Sigh.
Tone of voice do not transfer over the internet.
Oct 26 2018
next sibling parent reply Laurent =?UTF-8?B?VHLDqWd1aWVy?= <laurent.treguier.sink gmail.com> writes:
On Friday, 26 October 2018 at 21:16:54 UTC, 12345swordy wrote:
 It's a problem as we have the protected keyword already! There 
 is no reason for private to act it's protected in the same 
 module!
 If you want child to inherent your private member variables 
 then used protected.
 Otherwise private should mean that belongs to class A and only 
 to class A. If you wanted your child class to inherent private 
 member variables only in a module then we need a new access 
 attribute to avoid unwanted pitfuls.
`protected` isn't the same. `protected` will allow derived classes to access a member, even if they are not in the same module. `private` can only be accessed within a single module.
Oct 26 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 21:40:10 UTC, Laurent Tréguier 
wrote:
 On Friday, 26 October 2018 at 21:16:54 UTC, 12345swordy wrote:
 It's a problem as we have the protected keyword already! There 
 is no reason for private to act it's protected in the same 
 module!
 If you want child to inherent your private member variables 
 then used protected.
 Otherwise private should mean that belongs to class A and only 
 to class A. If you wanted your child class to inherent private 
 member variables only in a module then we need a new access 
 attribute to avoid unwanted pitfuls.
`protected` isn't the same. `protected` will allow derived classes to access a member, even if they are not in the same module. `private` can only be accessed within a single module.
...Did you read the other post that I made before you made that reply? I swear I am repeating myself ad nauseam.
Oct 26 2018
parent reply Laurent =?UTF-8?B?VHLDqWd1aWVy?= <laurent.treguier.sink gmail.com> writes:
On Friday, 26 October 2018 at 21:42:37 UTC, 12345swordy wrote:
 ...Did you read the other post that I made before you made that 
 reply?

 I swear I am repeating myself ad nauseam.
You simply seemed to be implying that private had the same effect as protected, which isn't the case. And yes, you are repeating yourself ad nauseam, since this is, I believe, your 3rd thread about this whole thing about the private keyword.
Oct 26 2018
next sibling parent Laurent =?UTF-8?B?VHLDqWd1aWVy?= <laurent.treguier.sink gmail.com> writes:
On Friday, 26 October 2018 at 21:46:27 UTC, Laurent Tréguier 
wrote:
 On Friday, 26 October 2018 at 21:42:37 UTC, 12345swordy wrote:
 ...Did you read the other post that I made before you made 
 that reply?

 I swear I am repeating myself ad nauseam.
You simply seemed to be implying that private had the same effect as protected, which isn't the case. And yes, you are repeating yourself ad nauseam, since this is, I believe, your 3rd thread about this whole thing about the private keyword.
*this is actually only the second, apologies.
Oct 26 2018
prev sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 21:46:27 UTC, Laurent Tréguier 
wrote:
 On Friday, 26 October 2018 at 21:42:37 UTC, 12345swordy wrote:
 ...Did you read the other post that I made before you made 
 that reply?

 I swear I am repeating myself ad nauseam.
You simply seemed to be implying that private had the same effect as protected, which isn't the case.
... How can I make my self any more clear here!? When I say y behaves like x it I don't means y is exactly the x! Nor does it imply that!
Oct 26 2018
next sibling parent reply Laurent =?UTF-8?B?VHLDqWd1aWVy?= <laurent.treguier.sink gmail.com> writes:
On Friday, 26 October 2018 at 22:01:42 UTC, 12345swordy wrote:
 On Friday, 26 October 2018 at 21:46:27 UTC, Laurent Tréguier 
 wrote:
 On Friday, 26 October 2018 at 21:42:37 UTC, 12345swordy wrote:
 ...Did you read the other post that I made before you made 
 that reply?

 I swear I am repeating myself ad nauseam.
You simply seemed to be implying that private had the same effect as protected, which isn't the case.
... How can I make my self any more clear here!? When I say y behaves like x it I don't means y is exactly the x! Nor does it imply that!
Then I don't know why the fact that we have protected means that the way private behaves is wrong. Anyway, I regret even partaking in this thread and I'll stop here, because from what I see: You would like private to be visible only in the class it was declared in, and nothing else. Instead it's visible from everything in the module (including, indeed, the derived classes). As others have pointed out, it's precisely said in the docs that private is about modules and not classes. It's not going to change as it would break code; if you have an idea of how to improve this, write a DIP like the one you started with nested modules, and present it here on the forum if you want people's opinion.
Oct 26 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 22:23:04 UTC, Laurent Tréguier 
wrote:
 On Friday, 26 October 2018 at 22:01:42 UTC, 12345swordy wrote:
 [...]
Then I don't know why the fact that we have protected means that the way private behaves is wrong. Anyway, I regret even partaking in this thread and I'll stop here, because from what I see: You would like private to be visible only in the class it was declared in, and nothing else. Instead it's visible from everything in the module (including, indeed, the derived classes). As others have pointed out, it's precisely said in the docs that private is about modules and not classes. It's not going to change as it would break code; if you have an idea of how to improve this, write a DIP like the one you started with nested modules, and present it here on the forum if you want people's opinion.
You are right, I am better off continuing writing the dip about nested modules then argue ad nauseam about this.
Oct 26 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Friday, 26 October 2018 at 22:42:42 UTC, 12345swordy wrote:
 You are right, I am better off continuing writing the dip about 
 nested modules then argue ad nauseam about this.
Actually, if the programming language does correctly, what it defines as correct (as defined by it's specification), then it is correct (for that programming language). "Correctness is the prime quality" - Bertrand Myers. Now...in an 'object-oriented' language, classes are the only 'modules'. That means, the class (the module) is the encapsulating unit by which you construct your program. D is not an object-oriented langauges - although it does have classes. Classes in D are NOT the modular units by which you are expected to construct your program; rather the module unit in D, is .. the 'module'. All decisions about classes in D, seem to derive from that concept. If you want the 'information hiding' capabilities that object-oriented languages offer to classes, then use an object-oriented language. Many come to D from object-oriented languages, and expect classes to operate in the same way in D, as they did in those languages. It aint going to happen - in D. Why? Because the designers of D expect you to use the module, not the class, as the encapsulating unit for constructing your program. Really, you are better off using a language that does what *you want* it to do, instead of getting the language to change it's concept of the modular unit. If you persist in trying to change D's concept of what the modular unit is, then you will only get the type of responses that you are already starting to get, and, you persist - it will likely get worse (based on the history around similiar discussions of D's implementation of classes). Move on, and use another language that doesn't redefine the traditional concept of a class, like D does - that is my advice ;-)
Oct 26 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Saturday, 27 October 2018 at 01:54:24 UTC, unprotected-entity 
wrote:

 D is not an object-oriented langauges - although it does have 
 classes.
It like you never read the overview https://dlang.org/overview.html or the wiki https://en.wikipedia.org/wiki/D_(programming_language)
 If you want the 'information hiding' capabilities that 
 object-oriented languages offer to classes, then use an 
 object-oriented language.
D IS an object-oriented language as much as c++, just not a pure one.
 Many come to D from object-oriented languages, and expect 
 classes to operate in the same way in D, as they did in those 
 languages. It aint going to happen - in D. Why?
"Have a short learning curve for programmers comfortable with programming in C, C++ or Java." Gee, I wonder why?
 Really, you are better off using a language that does what *you 
 want* it to do, instead of getting the language to change it's 
 concept of the modular unit.
You didn't read the dip that I wrote did you? Nowhere in the dip did I change the concept of the modular unit. I just remove the one module per file Limination. That is it.
Oct 26 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Saturday, 27 October 2018 at 02:49:00 UTC, 12345swordy wrote:
 D IS an object-oriented language as much as c++, just not a 
 pure one.
Most do not really understand the use of that term 'object-oriented'. In fact, an object can best be defined as: "a software machine allowing programs to access and modify a collection of data". That means D is object-oriented - it's just that the module is THE object in D). That translates to D treating the 'class' as a subordinate object (under the control of the module) - which is very different to
 "Have a short learning curve for programmers comfortable with 
 programming in C, C++ or Java."
 Gee, I wonder why?
over to D anytime soon - particulary if they have a fondness towards object-oriented programming using classes. But...I really *do* sympathise with your argument.. but, knowing what I know, you're better off using your mental energy on some other issue ;-)
 You didn't read the dip that I wrote did you? Nowhere in the 
 dip did I change the concept of the modular unit. I just remove 
 the one module per file Limination. That is it.
I actually found the dip draft confusing. After reading the justification at the start, for what was going to be proposed, and then reading what was actually proposed .. well.. to me, they don't seem to be entirely in sync with each other. In any case, given the justification, I would replace the proposed solution to say .."Go use another language that (already) does what you want it to do". If you have a fondness for classes, you will likely benefit from using another language ;-)
Oct 26 2018
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Saturday, 27 October 2018 at 04:44:58 UTC, unprotected-entity 
wrote:
 On Saturday, 27 October 2018 at 02:49:00 UTC, 12345swordy wrote:
 D IS an object-oriented language as much as c++, just not a 
 pure one.
Most do not really understand the use of that term 'object-oriented'.
I don't know about you, but you are in a minority when it comes to that particular definition.
 "Have a short learning curve for programmers comfortable with 
 programming in C, C++ or Java."
 Gee, I wonder why?
switching over to D anytime soon - particulary if they have a fondness towards object-oriented programming using classes.
It doesn't matter what you think. That is currently how D advertise itself right now. I came from a c++ background with the promise that it is "better". If you think this futile advertising then by all means create a new thread justifying your reasoning.
 You didn't read the dip that I wrote did you? Nowhere in the 
 dip did I change the concept of the modular unit. I just 
 remove the one module per file Limination. That is it.
I actually found the dip draft confusing. After reading the justification at the start, for what was going to be proposed, and then reading what was actually proposed .. well.. to me, they don't seem to be entirely in sync with each other.
This isn't helpful criticism at all. Can you be more specific?
 In any case, given the justification, I would replace the 
 proposed solution to say .."Go use another language that 
 (already) does what you want it to do".
LOL, sorry, but I didn't came here just for classes themselves. Programming in other language makes me miss D meta programming features.
Oct 27 2018
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 26 October 2018 at 22:01:42 UTC, 12345swordy wrote:
 On Friday, 26 October 2018 at 21:46:27 UTC, Laurent Tréguier 
 wrote:
 You simply seemed to be implying that private had the same 
 effect as protected, which isn't the case.
... How can I make my self any more clear here!? When I say y behaves like x it I don't means y is exactly the x! Nor does it imply that!
``` import std.stdio; class A { private int y; } class B : A { }; void main() { B b = new B(); b.y = 1; // Should be a compile error as class shouldn't have private int y. writeln(b.y); } ``` First, this really is about encapsulation and *not* inheritance. Even if class B is in another module, it would still inherit y, i.e. it would have its own copy of y. private working as intended. Second, A, B, and main are in the same module. The spec clearly says that everything in the same module has access to private members. I quoted it in the bug report and it's been quoted two or three times here. So main has access to y. If used to be that even if you moved the declaration of B to another module, then main would still have access to y through b. That was deemed to be a bug an is now deprecated. But as long as they are all in the same module, it's working as intended.
Oct 26 2018
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Saturday, 27 October 2018 at 03:20:43 UTC, Mike Parker wrote:


 still inherit y, i.e. it would have its own copy of y. private 
 working as intended.
I meant to say "would have its own copy of y, but would be unable to access it".
Oct 26 2018
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 27.10.18 05:20, Mike Parker wrote:
 If used to be that even if you moved the declaration of B to another 
 module, then main would still have access to y through b. That was 
 deemed to be a bug an is now deprecated.
That seems to make no sense at all (clearly main can access y though b by just implicitly casting to a superclass reference). Why was this done?
Oct 27 2018
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/27/18 7:40 AM, Timon Gehr wrote:
 On 27.10.18 05:20, Mike Parker wrote:
 If used to be that even if you moved the declaration of B to another 
 module, then main would still have access to y through b. That was 
 deemed to be a bug an is now deprecated.
That seems to make no sense at all (clearly main can access y though b by just implicitly casting to a superclass reference). Why was this done?
Read the bug report: https://issues.dlang.org/show_bug.cgi?id=15897 -Steve
Oct 27 2018
prev sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Saturday, 27 October 2018 at 03:20:43 UTC, Mike Parker wrote:
 On Friday, 26 October 2018 at 22:01:42 UTC, 12345swordy wrote:
 On Friday, 26 October 2018 at 21:46:27 UTC, Laurent Tréguier 
 wrote:
 You simply seemed to be implying that private had the same 
 effect as protected, which isn't the case.
... How can I make my self any more clear here!? When I say y behaves like x it I don't means y is exactly the x! Nor does it imply that!
``` import std.stdio; class A { private int y; } class B : A { }; void main() { B b = new B(); b.y = 1; // Should be a compile error as class shouldn't have private int y. writeln(b.y); } ``` First, this really is about encapsulation and *not* inheritance. Even if class B is in another module, it would still inherit y, i.e. it would have its own copy of y. private working as intended. Second, A, B, and main are in the same module. The spec clearly says that everything in the same module has access to private members. I quoted it in the bug report and it's been quoted two or three times here. So main has access to y. If used to be that even if you moved the declaration of B to another module, then main would still have access to y through b. That was deemed to be a bug an is now deprecated. But as long as they are all in the same module, it's working as intended.
Oh for the record, I had realized that I had embarrassed myself greatly with my own stupidity. Sorry. Alex
Oct 28 2018
prev sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Friday, 26 October 2018 at 21:16:54 UTC, 12345swordy wrote:
 On Friday, 26 October 2018 at 20:52:38 UTC, Stanislav Blinov 
 wrote:
 What is that all about!? Are you type of guy who like get into 
 fights?
I'm not the guy who stomped in here demanding answers from a language author regarding false assumptions.
 Class private member variables are behaving like they 
 protected class protected when creating derived class in the 
 same module.
Which is a problem because?..
 It's a problem as we have the protected keyword already! There 
 is no reason for private to act it's protected in the same 
 module!
"protected" exists solely for classes, not modules.
 If you want child to inherent your private member variables 
 then used protected.
The word is "access", not "inherit". But indeed, if you want child to have access to parent's state inaccessible to external code, you should use 'protected'. That's exactly how you can allow other people to access some of the sate even when they're inheriting in another module.
 Otherwise private should mean that belongs to class A and only 
 to class A. If you wanted your child class to inherent private 
 member variables only in a module then we need a new access 
 attribute to avoid unwanted pitfuls.
It feels like you don't understand how inheritance works. A derived class *does* inherit *all* of the parent's guts irrespective of where they're defined relative to each other, or what visibility attributes they have. It's just that some of the guts may not be accessible to the derived class. Parent's private state doesn't magically disappear from the derived class' bits.
 There's no contradiction. Within a module, you have access 
 to everything.
This is about inheritance not encapsulation. You shouldn't be accessing doors when they shouldn't exist in the first place.
So... use the language as intended
That is a huge moot point itself that should belong it own thread.
How so? You're arguing that the spec is wrong when it clearly works as it says in this particular case.
 and don't put things that  absolutely must not access private 
 data into the same module.
I repeat: This is about inheritance not encapsulation. You shouldn't be accessing doors when they shouldn't exist in the first place.
This *is* about encapsulation, which in itself is about visibility. "private" is strong encapsulation, "public" is weak encapsulation, "protected" is the middle ground. But a unit of encapsulation in D is a module, not a class.
 You are debunking a straw man.
Eh?
 Class is within a module. It's members are within a module. 
 Ergo, they're accessible even when private. Again, there's no 
 contradiction at all.
 Again you are debunking a straw man.
No. I'm explaining to you that your understanding of the spec is incorrect.
 So? As long as the "team" uses the same language, all it's 
 members should understand what "private" means *in that 
 language*.

There's absolutely no need for artificial restrictions.
Nonsense, safe and nogc are artificial restrictions. Code discipline is good behavior, even for yourself.
1) safe and nogc have nothing to do with visibility
You didn't say visibility, you said "artificial restrictions"
What was it that you said about strawmen? Your topic is about "private". "private" is a visibility attribute. Disallowing access to your own data within your own module, to code that you yourself are writing is unnecessary; it is an artificial restriction that serves no purpose.
 Yep, which is exactly why the language lets you do whatever 
 you want with symbols inside a module.
Really? Then why I can't get rid private member variables that class B inherent from class A that is marked "private". Do I have to mark them delete every time I inherent?
"private" doesn't get rid of anything. It simply disallows access outside of module. At least in D that's what it does. Again, perhaps there's something wrong with your understanding of inheritance.
 Tone of voice do not transfer over the internet.
Which is why you should've thought twice before demanding answers.
Oct 26 2018
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 22:00:21 UTC, Stanislav Blinov 
wrote:
 On Friday, 26 October 2018 at 21:16:54 UTC, 12345swordy wrote:
 [...]
 [...]
I'm not the guy who stomped in here demanding answers from a language author regarding false assumptions.
"who stomped in here". That is your imagination.
 [...]
 [...]
 "protected" exists solely for classes, not modules.
It like you not even trying to understand what I am saying here.
 [...]
The word is "access", not "inherit".
I know what I meant when I use the word "inherit". Don't play coy with me.
 But indeed, if you want child to have access to parent's state 
 inaccessible to external code, you should use 'protected'. 
 That's exactly how you can allow other people to access some of 
 the sate even when they're inheriting in another module.
*sigh*
 [...]
It feels like you don't understand how inheritance works. A derived class *does* inherit *all* of the parent's guts irrespective of where they're defined relative to each other, or what visibility attributes they have. It's just that some of the guts may not be accessible to the derived class. Parent's private state doesn't magically disappear from the derived class' bits.
 [...]
How so?
What does "use the language as intended" mean anyway?
 [...]
This *is* about encapsulation, which in itself is about visibility. "private" is strong encapsulation, "public" is weak encapsulation, "protected" is the middle ground. But a unit of encapsulation in D is a module, not a class.
You are addressing a straw man still.
 [...]
Eh?
 [...]
 [...]
No. I'm explaining to you that your understanding of the spec is incorrect.
Or poor reading compensation.
 [...]
What was it that you said about strawmen?
You literally use the words "artificial restrictions"!
 [...]
"private" doesn't get rid of anything. It simply disallows access outside of module. At least in D that's what it does. Again, perhaps there's something wrong with your understanding of inheritance.
 [...]
 Which is why you should've thought twice before demanding 
 answers.
No, that is you failing to follow the conversation. I am done.
Oct 26 2018
prev sibling parent reply Neia Neutuladh <neia ikeran.org> writes:
On Fri, 26 Oct 2018 18:16:38 +0000, 12345swordy wrote:
 Why private member variables behave like protected member variables in
 the same module? Can you explain your thought process when it comes to
 this design decision Walter Bright? Is there no way to mark the private
 member variables as "final" in the same module?
 
 -Alex
D's `private` within a module is identical to Java's `private` within a class and its nested classes. The following is valid Java: // Protections.java public class Protections { private void foo() { System.out.println("foo"); } public static class Bar { public void foo(Protections p) { p.foo(); } private void bar() { System.out.println("bar"); } } public static class Baz { private void bar(Bar b) { b.bar(); } } public static void main(String[] args) { new Bar().foo(new Protections()); new Baz().bar(new Bar()); } } If you maintain a D module, you are expected to maintain the whole module, so you should be able to determine when it's valid to access a private member. And this is useful. This is the same as Java's opinion that, if you wrote a class, you should be responsible its nested classes too, and vice versa, so you should be able to access private members across those classes. Also because it's useful. C++ uses `friend` instead: you explicitly mark what other types and functions can use your private variables. it annoying to refer to a class member. So there's no clear winning way of doing things. D has one way of working that's rather useful but somewhat surprising (probably largely because of Java programmers who aren't familiar with some aspects of Java, I'm guessing). The less surprising alternative stops you from doing some useful things.
Oct 26 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 18:57:00 UTC, Neia Neutuladh wrote:
 On Fri, 26 Oct 2018 18:16:38 +0000, 12345swordy wrote:
 [...]
D's `private` within a module is identical to Java's `private` within a class and its nested classes. The following is valid Java: [...]
Again I am referring to classes in the module not the module itself.
Oct 26 2018
next sibling parent Neia Neutuladh <neia ikeran.org> writes:
On Fri, 26 Oct 2018 19:28:43 +0000, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:57:00 UTC, Neia Neutuladh wrote:
 On Fri, 26 Oct 2018 18:16:38 +0000, 12345swordy wrote:
 [...]
D's `private` within a module is identical to Java's `private` within a class and its nested classes. The following is valid Java: [...]
Again I am referring to classes in the module not the module itself.
Perhaps you could show an example of what you want to forbid? I think that would be the most effective way for you to communicate what you mean.
Oct 26 2018
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/26/18 3:28 PM, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:57:00 UTC, Neia Neutuladh wrote:
 On Fri, 26 Oct 2018 18:16:38 +0000, 12345swordy wrote:
 [...]
D's `private` within a module is identical to Java's `private` within a class and its nested classes. The following is valid Java: [...]
Again I am referring to classes in the module not the module itself.
Classes in the module are in the module. So any classes in the module *are* the module itself. What it seems like you are saying is that you want non-derivatives to still be able to access private variables, but derivative classes are forbidden? Nothing personal, but this really doesn't make a lot of sense. I feel like maybe there is a misunderstanding. Note that the lack of ability to encapsulate data in classes or structs within a module has been discussed here a lot. It's not going to change, however, as it comes down to a deliberate choice between encapsulation and ease of implementation. -Steve
Oct 26 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 26 October 2018 at 21:05:56 UTC, Steven Schveighoffer 
wrote:
 On 10/26/18 3:28 PM, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:57:00 UTC, Neia Neutuladh 
 wrote:
 On Fri, 26 Oct 2018 18:16:38 +0000, 12345swordy wrote:
 [...]
D's `private` within a module is identical to Java's `private` within a class and its nested classes. The following is valid Java: [...]
Again I am referring to classes in the module not the module itself.
Classes in the module are in the module. So any classes in the module *are* the module itself. What it seems like you are saying is that you want non-derivatives to still be able to access private variables, but derivative classes are forbidden? Nothing personal, but this really doesn't make a lot of sense. I feel like maybe there is a misunderstanding.
There is a misunderstanding! I am asking why the child class have the parent class private member variables in the first place!!! Do I need to write a DIP for you guys to understand what the hell I am talking about!?
Oct 26 2018
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, October 26, 2018 3:30:25 PM MDT 12345swordy via Digitalmars-d 
wrote:
 On Friday, 26 October 2018 at 21:05:56 UTC, Steven Schveighoffer

 wrote:
 On 10/26/18 3:28 PM, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:57:00 UTC, Neia Neutuladh

 wrote:
 On Fri, 26 Oct 2018 18:16:38 +0000, 12345swordy wrote:
 [...]
D's `private` within a module is identical to Java's `private` within a class and its nested classes. The following is valid Java: [...]
Again I am referring to classes in the module not the module itself.
Classes in the module are in the module. So any classes in the module *are* the module itself. What it seems like you are saying is that you want non-derivatives to still be able to access private variables, but derivative classes are forbidden? Nothing personal, but this really doesn't make a lot of sense. I feel like maybe there is a misunderstanding.
There is a misunderstanding! I am asking why the child class have the parent class private member variables in the first place!!! Do I need to write a DIP for you guys to understand what the hell I am talking about!?
Derived classes _always_ have the private members of their base classes, because the base classes are part of the derived classes. Derived classes extend the base classes and literally have the base class members inside of them and wouldn't work properly if they didn't. However, if they're in separate modules, then the derived class does not have access to them. etc. The difference is that in D, if you then put them in the same module, the derived class then has access to the base class' member variables, because private is private to the module, not the class. You'd get the same in C++ if you made them friends, but you'd have to be explicit about it, since friends require you to be explicit about it. - Jonathan M Davis
Oct 26 2018
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/26/18 5:30 PM, 12345swordy wrote:
 On Friday, 26 October 2018 at 21:05:56 UTC, Steven Schveighoffer wrote:
 On 10/26/18 3:28 PM, 12345swordy wrote:
 On Friday, 26 October 2018 at 18:57:00 UTC, Neia Neutuladh wrote:
 On Fri, 26 Oct 2018 18:16:38 +0000, 12345swordy wrote:
 [...]
D's `private` within a module is identical to Java's `private` within a class and its nested classes. The following is valid Java: [...]
Again I am referring to classes in the module not the module itself.
Classes in the module are in the module. So any classes in the module *are* the module itself. What it seems like you are saying is that you want non-derivatives to still be able to access private variables, but derivative classes are forbidden? Nothing personal, but this really doesn't make a lot of sense. I feel like maybe there is a misunderstanding.
There is a misunderstanding! I am asking why the child class have the parent class private member variables in the first place!!!
You mean why are they present in the class instance? That's basic inheritance, no? If that wasn't the case, then you'd have serious issues: class C { private int x; void increment() {++x;} } class B : C {} void main() { auto b = new B; b.increment(); } If b didn't have an `x` in it, then how would this work? Again, I feel like there is a misunderstanding.
 Do I need to write a DIP for you guys to understand what the hell I am 
 talking about!?
I don't think writing the same words in another place is going to make them more understandable. -Steve
Oct 27 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Saturday, 27 October 2018 at 14:20:10 UTC, Steven 
Schveighoffer wrote:
 If b didn't have an `x` in it, then how would this work?
Only in D, does b have x in it.
Oct 27 2018
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/27/18 11:24 AM, unprotected-entity wrote:
 On Saturday, 27 October 2018 at 14:20:10 UTC, Steven Schveighoffer wrote:
 If b didn't have an `x` in it, then how would this work?
Only in D, does b have x in it.
This isn't correct. I'd write examples in each of those languages, but don't have the time right now. -Steve
Oct 27 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Saturday, 27 October 2018 at 16:19:03 UTC, Steven 
Schveighoffer wrote:
 This isn't correct. I'd write examples in each of those 
 languages, but don't have the time right now.

 -Steve
I have plenty of time ;-) (in any case, my point is not to make an argument out of this, I was stating a fact). That D does it differently, is fine, if that's how D want to do it. But people coming to D, will be very surprised, and will have to come to terms with it, or not. ====== C++ ============= class C { private: int x = 0; public: void increment() {++x;} }; class B : public C {}; int main() { B b; b.increment(); b++; // no way! not in C++ return 0; } ===== Java ============== class C { private int x; public void increment() { ++x; } } class B extends C {} public class Program { public static void main(String[] args) { B b = new B(); b.increment(); b++; // seriously. you really think this is going to happen? Not in Java it aint. } } class C { private int x; public void increment() { ++x; } } class B : C {} public class Program { public static int Main() { B b = new B(); b.increment(); return 0; } } ===== D ======== module test; class C { private int x; public void increment() { ++x; } } class B : C {} void main() { B b = new B; b.increment(); b.x++; // sure, no problem. I'll do that for you, cause I'm D. } ===== THE END =======
Oct 28 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, October 28, 2018 2:36:06 AM MDT unprotected-entity via 
Digitalmars-d wrote:
 On Saturday, 27 October 2018 at 16:19:03 UTC, Steven

 Schveighoffer wrote:
 This isn't correct. I'd write examples in each of those
 languages, but don't have the time right now.

 -Steve
I have plenty of time ;-) (in any case, my point is not to make an argument out of this, I was stating a fact). That D does it differently, is fine, if that's how D want to do it. But people coming to D, will be very surprised, and will have to come to terms with it, or not.
True enough, but in reality, it seems that most people coming to D don't even notice. After all, none of the code outside of the module containing the class has access to the class' private members, and if you don't try to access the class' private members using any of the other code inside the same module, then you won't notice. Plenty of folks incorrectly assume that D's private works the same as private in other languages, never run into problems with it, and have no clue that it works any differently. It really only matters when you're actually looking to emulate friends, and then you find out pretty fast. Occasionally, it comes up and folks complain about it, but honestly, I don't think that there have been threads complaining about it in the newsgroup more than a handful of times - if that - over the last ten years. Mostly, if it does come up, it's just that's someone is suprised to finally find out that private is private to the module and not the class. I don't think that it's uncommon for folks code for years in D without realizing it. Sure, once someone learns about it, they have to come to terms with it, and they may or may not be unhappy about it, but it's such a non-issue in practice that a lot of folks simply don't notice. - Jonathan M Davis
Oct 28 2018
prev sibling next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 27 October 2018 at 15:24:19 UTC, unprotected-entity 
wrote:
 Only in D, does b have x in it.


Well, they have it, it is just an error to use it from there.
Oct 27 2018
prev sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Saturday, 27 October 2018 at 15:24:19 UTC, unprotected-entity 
wrote:
 On Saturday, 27 October 2018 at 14:20:10 UTC, Steven 
 Schveighoffer wrote:
 If b didn't have an `x` in it, then how would this work?
Only in D, does b have x in it.
It might be that you're confusing "have" to mean "has access". In other languages b doesn't have access to x, but it most definitely has an x inside of it.
Oct 27 2018
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, October 27, 2018 12:06:36 PM MDT Atila Neves via Digitalmars-d 
wrote:
 On Saturday, 27 October 2018 at 15:24:19 UTC, unprotected-entity

 wrote:
 On Saturday, 27 October 2018 at 14:20:10 UTC, Steven

 Schveighoffer wrote:
 If b didn't have an `x` in it, then how would this work?
Only in D, does b have x in it.
It might be that you're confusing "have" to mean "has access". In other languages b doesn't have access to x, but it most definitely has an x inside of it.
And depending on the language, you can even give access to them - e.g. in C++, friends could be used to give access, though it would be a bit odd, since normally you'd just used protected for such a use case rather than making the derived class a friend. Either way, Derived classes _are_ base classes and literally contain their base class members. They wouldn't work when used via a pointer of the base class type otherwise. So, yeah, it's a question of having access and not whether they're there. They have to be there. The combination of D's private being private to the module, not the class, and putting the derived class in the same module as the base class simply creates a situation that you wouldn't normally get in other languages with regards to access. The layout of the class itself should actually be minor differences in how it actually lays out classes, but the fact that a base class is physically part of a derived class is common to all of them, and unless the language requires that all base classes be pure interfaces, I don't see how it could possibly be otherwise. - Jonathan M Davis
Oct 27 2018
prev sibling parent reply unprotected-entity <unprotected-entity unprotected-entity.gmail.com> writes:
On Saturday, 27 October 2018 at 18:06:36 UTC, Atila Neves wrote:
 On Saturday, 27 October 2018 at 15:24:19 UTC, 
 unprotected-entity wrote:
 On Saturday, 27 October 2018 at 14:20:10 UTC, Steven 
 Schveighoffer wrote:
 If b didn't have an `x` in it, then how would this work?
Only in D, does b have x in it.
It might be that you're confusing "have" to mean "has access". In other languages b doesn't have access to x, but it most definitely has an x inside of it.
was declared private to C. In D, it's not private to C, or anything else in the same module. I know the reasoning behind this, but it's just awful, and invites bugs into your code. oh... so you accidently typed b.x++ in main().. or someother code outside of the class), instead of b.increment() ...well...to bad. Yes.. it's an old discussion, I know..but an unprotected entity is a useless programming construct, and will invite bugs into your program.
Oct 27 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, October 27, 2018 10:38:53 PM MDT unprotected-entity via 
Digitalmars-d wrote:
 On Saturday, 27 October 2018 at 18:06:36 UTC, Atila Neves wrote:
 On Saturday, 27 October 2018 at 15:24:19 UTC,

 unprotected-entity wrote:
 On Saturday, 27 October 2018 at 14:20:10 UTC, Steven

 Schveighoffer wrote:
 If b didn't have an `x` in it, then how would this work?
Only in D, does b have x in it.
It might be that you're confusing "have" to mean "has access". In other languages b doesn't have access to x, but it most definitely has an x inside of it.
was declared private to C. In D, it's not private to C, or anything else in the same module. I know the reasoning behind this, but it's just awful, and invites bugs into your code. oh... so you accidently typed b.x++ in main().. or someother code outside of the class), instead of b.increment() ...well...to bad. Yes.. it's an old discussion, I know..but an unprotected entity is a useless programming construct, and will invite bugs into your program.
LOL. I have no clue how you just accidentally use a member variable. But if that's a concern, it's exactly the same concern that you would have in C++ or Java from within a functions inside a class that you don't want accessing a particular member variable. D just puts the demarcation line at the module instead of the class. It doesn't really change much ultimately in terms of needing to being aware of what is supposed to be accessed where for anything that has access. And if you want to further restrict access, then put classes in their own modules. Problem solved. Some of the languages that define private the way that some folks want already require that anyway. Honestly, I have _never_ seen a bug caused by the fact that D makes private restrict access to the module level and not the class or struct level. From everything I've seen, this is entirely an issue of people not liking the idea and not something that's an actual problem in practice. - Jonathan M Davis
Oct 27 2018
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 28/10/2018 6:11 PM, Jonathan M Davis wrote:
 Honestly, I have_never_  seen a bug caused by the fact that D makes private
 restrict access to the module level and not the class or struct level. From
 everything I've seen, this is entirely an issue of people not liking the
 idea and not something that's an actual problem in practice.
Which is why when we have "anonymous" people posting these, we tend to not reply to them. It does not lead to useful discussions for anyone.
Oct 27 2018
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 28 October 2018 at 04:38:53 UTC, unprotected-entity 
wrote:

 oh... so you accidently typed b.x++ in main().. or someother 
 code outside of the class), instead of b.increment() 
 ...well...to bad.
You can make the same mistake inside the class: class Foo { private int x; void increment() {...} ... void doSomethingInternal() { x++; } } How is making that mistake outside of that final curly brace any different or any worse? It's all in the same file.
Oct 27 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Sunday, 28 October 2018 at 05:28:31 UTC, Mike Parker wrote:
 You can make the same mistake inside the class:

 class Foo {
    private int x;
    void increment() {...}
    ...
    void doSomethingInternal() { x++; }
 }

 How is making that mistake outside of that final curly brace 
 any different or any worse? It's all in the same file.
Except, that (I assume) a module in D is meant to be more than just a single class. If that's not the case, then my argument is irrelevant. If it is the case, then you presumably would have a great deal more code in your module, than you would in a single class. Hence, greater likelihood of mistakingly accessing a private member of some class defined within the module, somewhere. In any case, it does undermine the principle of encapsulation (assuming you agree that a class deserves to be a unit of encapsulation). In, it's nothing more than a convenient hack, really. There is not a third option here.
Oct 28 2018
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 28 October 2018 at 11:27:01 UTC, unprotected-entity 
wrote:
 On Sunday, 28 October 2018 at 05:28:31 UTC, Mike Parker wrote:
 How is making that mistake outside of that final curly brace 
 any different or any worse? It's all in the same file.
Except, that (I assume) a module in D is meant to be more than just a single class. If that's not the case, then my argument is irrelevant.
Modules can contain as many classes as you like or none at all. That doesn't change anything. It's still all in the same file.
 If it is the case, then you presumably would have a great deal 
 more code in your module, than you would in a single class.
 Hence, greater likelihood of mistakingly
 accessing a private member of some class defined within the 
 module, somewhere.
And full access to the file to change it if you do make that mistake. No encapsulation broken.
 In any case, it does undermine the principle of encapsulation 
 (assuming you agree that a class deserves to be a unit of 
 encapsulation).
In D, the module is the unit of encapsulation, not the class.
Oct 28 2018
next sibling parent reply unprotected-entity <unprotected-entity unprotected-entity.gmail.com> writes:
On Sunday, 28 October 2018 at 11:32:07 UTC, Mike Parker wrote:
 In D, the module is the unit of encapsulation, not the class.
Again. this is not entirely correct. ----- class Foo { private int i; } void main() { {Foo f;} f.i++; } ---- It's really hard to have a converstation when posts are being checked by 'someone', at 'their leisure', before (or if) they ever get posted??
Oct 28 2018
parent Neia Neutuladh <neia ikeran.org> writes:
On Mon, 29 Oct 2018 05:13:08 +0000, unprotected-entity wrote:
 On Sunday, 28 October 2018 at 11:32:07 UTC, Mike Parker wrote:
 In D, the module is the unit of encapsulation, not the class.
Again. this is not entirely correct. ----- class Foo { private int i; } void main() { {Foo f;} f.i++; } ---- It's really hard to have a converstation when posts are being checked by 'someone', at 'their leisure', before (or if) they ever get posted??
There are two concepts here: scope and encapsulation. This is a demonstration of scope. A variable that is not in scope might point to data that doesn't currently exist, or there might simply be no way to refer to that data in an unambiguous way. In your example, an optimizing compiler might have destroyed `f` and reclaimed its memory at the end of its block. A related example shows the ambiguity as well: --- class Foo { private int i; } void main() { {Foo f = new Foo;} {Foo f = new Foo;} f.i++; } --- Similarly with your function example, there's no general way to refer to variables in other functions. Your function can't know where it's called from, so it can't refer to variables higher up on the stack. Variables that are lower down on the stack have already been destroyed. Plus with recursion, you can't specify which copy of a variable you're talking about.
Oct 29 2018
prev sibling parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Sunday, 28 October 2018 at 11:32:07 UTC, Mike Parker wrote:
 In D, the module is the unit of encapsulation, not the class.
That is not entirely correct. --- module test; import std.stdio; void test() { int a; } void main() { writeln(a); } // Error: undefined identifier 'a' --- The D module still considers a function to be it's own unit of encapsulation. Classes no longer have that status in D. Now, for the small number of D users, it seems a relative non-issue. Fine. I wonder if that would still be the case, if millions and discovered, likely by accident, or by some obscure bug in their code), that a class is not considered a unit of encapsulation anymore. I think you would then have a much harder time convincing larger numbers of programmers, that D has done a good thing here (n terms of architecturing better software) by altering the most important encapsulating property of a class - private. I'm guarantee, that you'd be getting a *lot* more DIP's that try to address it ;-) I think Go and Rust have done it better, somewhat, in that they don't even have classes. So you are forced to rethink your design anyway (if you want to use those languages) Having said that, I am yet to hear a really good argument, as for why everything in a module *must* be your friends. Encapsulation, is not about having lots of friends that can poke at your private parts - no matter what language it is. But in a language that offers 'classes', but NOT as unit of encapsulation in its own right (within a module that is), well, I find that rather odd, and disconcerting (in terms of reasonable guarantees of your softwares correctness). I understand that practical considerations are often more important, and useful, that theoretical standpoints, but even so, I do not see the wholesale practicality and usefulness of the decision made in D, in relation to this matter. Yes, there are situations in which it might be useful, I get it. But surely not every situation?
Oct 28 2018
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Monday, 29 October 2018 at 05:13:22 UTC, unprotected-entity 
wrote:

 Having said that, I am yet to hear a really good argument, as 
 for why everything in a module *must* be your friends. 
 Encapsulation, is not about having lots of friends that can 
 poke at your private parts - no matter what language it is.
I've always understood encapsulation to be about the public API. I've generally seen two primary reasons given as to the purpose behind managing access: hiding complexity, and managing change. For the first, consumers of an API need not know or care about the implementation details. Access modifiers allow the producers of an API to hide the details of the implementation and only expose what the consumer actually needs. For the second, changes to the implementation of an API should ideally not impact the public API. Access modifiers allow the producer to segregate the changeable from the unchangeable. From that perspective, D's system does not break encapsulation. From outside the module, publicly accessible symbols (including classes, structs, their members, and module-scope declarations) provide the public API for which change should be minimal. From inside the module, encapsulation is achieved with the package and private access modifiers. In my opinion, you're making a purely abstract argument. Conceptually, the class is its own entity, true. But anyone who can edit the file in which the class resides can also edit the class implementation. Encapsulation inside the file is rather pointless. I understand the argument about accidentally bypassing accessors to directly modify private members that shouldn't be modified. But the same thing can happen from inside the class. IIRC, one of the tips in Effective Java was to always use accessors to modify member variables even inside the class, and it's fairly common in Java to do so, to avoid causing subtle bugs like that. But the language doesn't require it, nor should it. I see D's modules in the same light. There's no need to add more complexity to the language to solve a problem that is arguably rare in practice. If you're worried about accessing private members in a module, then use a naming convention that clearly marks private variables (I use an underscore in front, _foo) and never directly modify any variable with an underscore. If you're worried about other people doing it, split your modules and use the package access modifier to organize your package. The tools to solve this potential issue are there. We don't need more. Anyway, I'm not the one who needs convincing. And I have a high degree of confidence that the ones who do need convincing won't be. There has yet to be a strong enough argument to change this behavior.
Oct 28 2018
next sibling parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 06:15:25 UTC, Mike Parker wrote:
 Encapsulation inside the file is rather pointless.
Say that to yourself a few times, and see if your view changes ;-) (btw. just take a look at the length of some 'files', within Phobos - I mean, gee, I really hope the developer of those files did not share your view) In any case, encapsulation in a file, still exists, just not so much for classes - function still have it, scope braces still have it..etc..etc... but one of the most important constructs in programming, the class, does not.
 I understand the argument about accidentally bypassing 
 accessors to directly modify private members that shouldn't be 
 modified.
It's not just that it could happen 'by accident', it's that D actively encourages this, by making 'private' (within a module), a completely useless construct. It's there by default. Just how often does one need to access the private members of a class, within a module?
Oct 29 2018
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity 
wrote:
 On Monday, 29 October 2018 at 06:15:25 UTC, Mike Parker wrote:
 Encapsulation inside the file is rather pointless.
Say that to yourself a few times, and see if your view changes ;-)
I have, and it hasn't :-)
 (btw. just take a look at the length of some 'files', within 
 Phobos - I mean, gee, I really hope the developer of those 
 files did not share your view)
Classes can take up just as much space, presenting the same potential issue.
 In any case, encapsulation in a file, still exists, just not so 
 much for classes
 - function still have it, scope braces still have 
 it..etc..etc... but one of the most important constructs in 
 programming, the class, does not.
I don't think I've ever heard of anyone speak of encapsulation in terms of function scopes and anonymous scopes. That's a fairly narrow definition. At any rate, I don't put variables inside a function to keep them out of the public API. And yes, classes do have encapsulation. Private class members are hidden from the public API.
 It's not just that it could happen 'by accident', it's that D 
 actively encourages this, by making 'private' (within a 
 module), a completely useless construct.

 It's there by default.
Being the default isn't the same as encouraging it.
 Just how often does one need to access the private members of a 
 class, within a module?
I can't speak for others, but it's a feature I use fairly often. I tend to design aggregates and free functions to the module, as a cohesive whole, rather than as separate parts. If I want separate parts, I put them in different modules and use `package` for the bits that need to stay out of the public API. Works a treat.
Oct 29 2018
next sibling parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 10:32:00 UTC, Mike Parker wrote:
 I can't speak for others, but it's a feature I use fairly 
 often. I tend to design aggregates and free functions to the 
 module, as a cohesive whole, rather than as separate parts. If 
 I want separate parts, I put them in different modules and use 
 `package` for the bits that need to stay out of the public API. 
 Works a treat.
Well. In the end, it seems like nobody will be able to convince Walter and Andrei (and you too it seems), that there is some real practical merit, in allowing a class within a module, to have the capacity to protect its private parts. I find that really odd. (I mean, really, really odd). That doesn't translate to..hey ..lets change the way 'private' works within a module ...so that we can break everyones code... But there are realtive easy ways to give the programmer more choice over this, without 'complexity' becoming a geniune issue (that's just used by some as an excuse not to do anything). But nobody seems willing to listen to those proposals. Doesn't affect me. I already have great programming languages that already do what I want them to do. I'd like to 'play' with D. But when private actually means public (inside a module), and when I the programmer have no control over this (within a module), then, my interest in D cannot be sustained. If you have a class in a module, and you have anything else in that module, then the encapsulation of your class is immediately suspect - and anyone reviewing your code has to go looking to see exactly what you're doing - because what the class says about it interface, is irrelevant.
Oct 29 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, October 29, 2018 7:52:47 AM MDT unprotected-entity via 
Digitalmars-d wrote:
 On Monday, 29 October 2018 at 10:32:00 UTC, Mike Parker wrote:
 I can't speak for others, but it's a feature I use fairly
 often. I tend to design aggregates and free functions to the
 module, as a cohesive whole, rather than as separate parts. If
 I want separate parts, I put them in different modules and use
 `package` for the bits that need to stay out of the public API.
 Works a treat.
Well. In the end, it seems like nobody will be able to convince Walter and Andrei (and you too it seems), that there is some real practical merit, in allowing a class within a module, to have the capacity to protect its private parts. I find that really odd. (I mean, really, really odd).
If anything, many of us have been convinced of the opposite by actually using D. The way that D treats private is pratical and useful, and adding a way to further restrict access to member variables of classes would just be a further complication to the language with little to no pratical benefit. If you don't like that, that's fine. I don't think that any of use like _every_ design decision made in D, but many of us do like this design decision, and plenty of folks had a negative reaction to it when they initially found out. However, experience tends to show that D's design decision here works extremely well. - Jonathan M Davis
Oct 29 2018
next sibling parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis 
wrote:
 If anything, many of us have been convinced of the opposite by 
 actually using D. The way that D treats private is pratical and 
 useful, and adding a way to further restrict access to member 
 variables of classes would just be a further complication to 
 the language with little to no pratical benefit.

 If you don't like that, that's fine. I don't think that any of 
 use like _every_ design decision made in D, but many of us do 
 like this design decision, and plenty of folks had a negative 
 reaction to it when they initially found out. However, 
 experience tends to show that D's design decision here works 
 extremely well.

 - Jonathan M Davis
It's not (just) that I don't like it, it's that I don't like not giving the programmer the tool to better encapsulate their code (specifically classes) *within* a module. Well, as Walter said in a previous post, "Being able to declare a "friend" that is somewhere in some other file runs against notions of encapsulation." My argument is not too dissimilar. Forcing everything in a file, to be friends with each other, runs against the notions of encapsulation. Sure, put the class in its own module. But then you lose the encapsulation property and convenience, of the module. So you worse off, no matter how you look at it, in D. The difference between the C++ way, and the D way, is that the C++ way (friends) is not really encouraged - i.e. it's mostly for corner cases - it's not meant to be how you go about architecturing your software - surely. In D however, it's exactly how you're meant to do it - it's by design - it's reaching out and saying, this is how you should do it. D seems to be proud, that you cannot encapsulate a class, within a module, from other code also in that module. If In any case, I don't really care so much about D, but about good design. And given what I've seen in phobos..well... I'm still looking for the 'design'. All I see are gigantic modules full of code...that does who knows what to each other..cause they're all friends and can do whatever they like to each other, in D.
Oct 29 2018
parent reply Atila Neves <atila.neves gmail.com> writes:
On Monday, 29 October 2018 at 23:15:58 UTC, unprotected-entity 
wrote:
 On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis 
 wrote:

 It's not (just) that I don't like it, it's that I don't like 
 not giving the programmer the tool to better encapsulate their 
 code (specifically classes) *within* a module.
You don't need to protect code in your module from other code in your module. If you do, put them in different modules.
 In D however, it's exactly how you're meant to do it - it's by 
 design - it's reaching out and saying, this is how you should 
 do it.
It _is_ how you should do it, but not with giant modules. Just have smaller modules.
  D seems to be proud, that you cannot encapsulate a class, 
 within a module, from other code also in that module. If 

Java doesn't compare - every class is in its own file. If you want to write D code Java style, and have `private` work the same way, then have a class per module. As for C++, one could argue that it encourages the practice of having source files implement multiple classes, which is part of the reason anyone uses `friend` there anyway!
 And given what I've seen in phobos..well... I'm still looking 
 for the 'design'.
There are parts of Phobos that aren't very well designed, especially the older code. There are also parts that are great (std.experimental.allocator for instance).
 All I see are gigantic modules full of code...that does who 
 knows what to each other..cause they're all friends and can do 
 whatever they like to each other, in D.
Yeah, that's not good. But the barrier to change the standard library is higher so I'm mostly ok with that.
Nov 01 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Thursday, 1 November 2018 at 14:17:13 UTC, Atila Neves wrote:
 On Monday, 29 October 2018 at 23:15:58 UTC, unprotected-entity 
 wrote:
 On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis 
 wrote:

 It's not (just) that I don't like it, it's that I don't like 
 not giving the programmer the tool to better encapsulate their 
 code (specifically classes) *within* a module.
You don't need to protect code in your module from other code in your module. If you do, put them in different modules.
That typically involves creation of files, which is not always ideal if you are working with code that is considerably small.
Nov 01 2018
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Nov 01, 2018 at 04:19:57PM +0000, 12345swordy via Digitalmars-d wrote:
 On Thursday, 1 November 2018 at 14:17:13 UTC, Atila Neves wrote:
 On Monday, 29 October 2018 at 23:15:58 UTC, unprotected-entity wrote:
 On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis wrote:
 It's not (just) that I don't like it, it's that I don't like not
 giving the programmer the tool to better encapsulate their code
 (specifically classes) *within* a module.
You don't need to protect code in your module from other code in your module. If you do, put them in different modules.
That typically involves creation of files, which is not always ideal if you are working with code that is considerably small.
Java also enforces, by policy, the creation of a separate file for every public class. This is no different. T -- Genius may have its limitations, but stupidity is not thus handicapped. -- Elbert Hubbard
Nov 01 2018
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Thursday, 1 November 2018 at 16:32:23 UTC, H. S. Teoh wrote:
 Java also enforces, by policy, the creation of a separate file 
 for every public class.
So what? I thought this is D not Java.
Nov 01 2018
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Nov 01, 2018 at 04:58:07PM +0000, 12345swordy via Digitalmars-d wrote:
 On Thursday, 1 November 2018 at 16:32:23 UTC, H. S. Teoh wrote:
 Java also enforces, by policy, the creation of a separate file for
 every public class.
So what? I thought this is D not Java.
[...] Yes, and I'm glad I can (mostly) get away from Java in my current Android project, thanks to cross-compiling with LDC. :-P But the point is that it's not all that onerous to have the file/module as the unit of encapsulation. It's not as if your modern filesystem would die or suffer severe performance problems if you have a couple of extra files in your source tree. And any competent IDE / code editor / build system should have no problems dealing with an extra file or two, so I'm not sure I understand why this is such a big hangup for you. Code in a module should be written to work nicely with each other in the first place, and doesn't need to be protected from each other. If they do, then just put them in separate files, job done. And if for whatever reason you absolutely MUST have everything in a single file yet insulated from each other, there's always the option of pre-processing your code with an external tool to split them up into temporary separate files and compile those instead of the file you edit, then you can have your cake and eat it too -- it will literally not compile if the code tries to call something it's not "supposed" to. (Yes, I have no qualms about preprocessing / auto-generating code, even D code, in my projects. In my current project I have two .d files that are auto-generated from external data. I *could* have done it in CTFE with mixins, but that would consume a boatload more of RAM and slow down compilation by an order of magnitude, so it's just back to the trusty old writefln to print D code from a utility program and then compile the result. Abstract all of that away in your build script, and you won't even notice it afterwards. And if your build system can't reliably handle something like this, you need a new build system.) T -- Time flies like an arrow. Fruit flies like a banana.
Nov 01 2018
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Thursday, 1 November 2018 at 17:14:51 UTC, H. S. Teoh wrote:
 On Thu, Nov 01, 2018 at 04:58:07PM +0000, 12345swordy via 
 Digitalmars-d wrote:
 [...]
[...] Yes, and I'm glad I can (mostly) get away from Java in my current Android project, thanks to cross-compiling with LDC. :-P [...]
I don't mind creating a tool to automatically copy past code in it's own module. Though I rather use attributes and create compile time instructions for it, but that is venturing into macro territory and we all know how difficult that is to persuade the two into accepting it.
Nov 01 2018
prev sibling parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Thursday, 1 November 2018 at 16:32:23 UTC, H. S. Teoh wrote:
 Java also enforces, by policy, the creation of a separate file 
 for every public class.  This is no different.


 T
If I wanted Java in D, I already have Java - which does a better job at being Java, than D. Also, I do not consider a single class, to be such a big bucket of code, that it should necessarily be a module all of it's own. Again, D kind forces this onto anyone coming from a class based, oop langauge - but only because D won't all private to be private in modules. And I don't know many class-based oo programmers, that find that acceptable. The only options D give such programmers, is: (a) stiff, stick to you current language if you don't like how D does it. (b) make sure you only ever have one class in a module in D. (c) stop thinking like that, and start thinking like D apparently wants you to think. I don't believe langauges should force a particular design upon the programmer. I'm not big fan of inheritance either, despite it being a valid and useful way to architect your solution. I like self-contained classes - and would like to have more than one self-contained class in a module. Java requires that only one can be public, which is a design pain point for me, that forces you into Java like design. It is not too much to ask, in my opinion, to have a 'strict private' like concept in D, which does everything private does (so it's not a breaking change), but additionally, keeps it private within the module too. That would also give the programmer, the option to write unit-tests that cannot access private parts. That surely would be a good thing (again, it's an option for the programmers - it's not forced upon them). Argue about how that should be done (syntax), fine. But telling programmers they only have the 3 options mentioned above, is kinda sad. Those do don't like the change, are really not that affected. They can just keep doing what they've always done. A good option for the syntax, would ensure it's immediately clear, that the programmer want their private parts, to remain private. How difficult/complex that would be, to actually implement, well that's a discussion that would interest me. But nobody is benefitting from just saying 'no' all the time. It's not about securing your code from other code in the module. It's about clean architecture.
Nov 01 2018
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 1 November 2018 at 23:23:55 UTC, unprotected-entity 
wrote:
 It's about clean architecture.
If you use interfaces correctly, there will be no private members accessible regardless of privacy and D's module system. interface I {} class B : I {} void workWithIt(I i) { // nothing in B is accessible without ugly casts! }
Nov 01 2018
next sibling parent unprotected-entity <unprotected-entity gmail.com> writes:
On Friday, 2 November 2018 at 00:54:43 UTC, Adam D. Ruppe wrote:
 If you use interfaces correctly, there will be no private 
 members accessible regardless of privacy and D's module system.

 interface I {}
 class B : I {}

 void workWithIt(I i) {
     // nothing in B is accessible without ugly casts!
 }
".. but it would be tenuous to argue that transparency was a positive contributor; more plausibly, it was a risk minimized by intensive management." - Andrei Alexandrescu - page 200 Now, I might be accused of taking that out of context, but am I really? In D, public is the default (I wonder how many realise this, when they come to D, let alone the issue with private). " .. (heck, public sets the bar pretty low.. )." - Andrei Alexandrescu - page 202 So, in D, the bar is already pretty low? Also, in D, there simply is no way to get privacy within the module. Just how low does the bar get, in D? (to quote informally), It's a transparent, white box, 'everything knows everything' approach to designing software - page 199 (again, i could be accused of taking this out of context, but am i really?) To me, D modules are 'a risk minmized by intensive management' (perhaps using the techniques you've demonstrated ;-) But gee, the bar is soooooo low.... in D.
Nov 02 2018
prev sibling parent Atila Neves <atila.neves gmail.com> writes:
On Friday, 2 November 2018 at 00:54:43 UTC, Adam D. Ruppe wrote:
 On Thursday, 1 November 2018 at 23:23:55 UTC, 
 unprotected-entity wrote:
 It's about clean architecture.
If you use interfaces correctly, there will be no private members accessible regardless of privacy and D's module system. interface I {} class B : I {} void workWithIt(I i) { // nothing in B is accessible without ugly casts! }
Yeah, if you're doing OOP and you're not passing interfaces around, you're doing it wrong.
Nov 02 2018
prev sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Thursday, 1 November 2018 at 16:19:57 UTC, 12345swordy wrote:
 On Thursday, 1 November 2018 at 14:17:13 UTC, Atila Neves wrote:
 On Monday, 29 October 2018 at 23:15:58 UTC, unprotected-entity 
 wrote:
 On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis 
 wrote:

 It's not (just) that I don't like it, it's that I don't like 
 not giving the programmer the tool to better encapsulate 
 their code (specifically classes) *within* a module.
You don't need to protect code in your module from other code in your module. If you do, put them in different modules.
That typically involves creation of files, which is not always ideal if you are working with code that is considerably small.
If the code is considerably small you don't need private. You don't need any good engineering principles at all, use goto to your heart's content. It just doesn't matter. That makes as much sense to me as introducing a keyword to protect a class from itself.
Nov 01 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Thursday, 1 November 2018 at 17:58:34 UTC, Atila Neves wrote:
 On Thursday, 1 November 2018 at 16:19:57 UTC, 12345swordy wrote:
 On Thursday, 1 November 2018 at 14:17:13 UTC, Atila Neves 
 wrote:
 On Monday, 29 October 2018 at 23:15:58 UTC, 
 unprotected-entity wrote:
 On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis 
 wrote:

 It's not (just) that I don't like it, it's that I don't like 
 not giving the programmer the tool to better encapsulate 
 their code (specifically classes) *within* a module.
You don't need to protect code in your module from other code in your module. If you do, put them in different modules.
That typically involves creation of files, which is not always ideal if you are working with code that is considerably small.
If the code is considerably small you don't need private. You don't need any good engineering principles at all, use goto to your heart's content. It just doesn't matter.
Not the point. We talking about encapsulating code which involves creation of another modules which always involved in creation of another file. Which is not always good solution if your code is remarkably small.
 That makes as much sense to me as introducing a keyword to 
 protect a class from itself.
It the equivalent of building another house to give your new child its own room, when you can simply assign a room in the house that you already have.
Nov 01 2018
parent reply Atila Neves <atila.neves gmail.com> writes:
On Thursday, 1 November 2018 at 18:30:33 UTC, 12345swordy wrote:
 On Thursday, 1 November 2018 at 17:58:34 UTC, Atila Neves wrote:
 On Thursday, 1 November 2018 at 16:19:57 UTC, 12345swordy 
 wrote:
 On Thursday, 1 November 2018 at 14:17:13 UTC, Atila Neves 
 wrote:
 On Monday, 29 October 2018 at 23:15:58 UTC, 
 unprotected-entity wrote:
 On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M 
 Davis wrote:

 It's not (just) that I don't like it, it's that I don't 
 like not giving the programmer the tool to better 
 encapsulate their code (specifically classes) *within* a 
 module.
You don't need to protect code in your module from other code in your module. If you do, put them in different modules.
That typically involves creation of files, which is not always ideal if you are working with code that is considerably small.
If the code is considerably small you don't need private. You don't need any good engineering principles at all, use goto to your heart's content. It just doesn't matter.
Not the point. We talking about encapsulating code which involves creation of another modules which always involved in creation of another file. Which is not always good solution if your code is remarkably small.
That wasn't my point either. My point is that if your code is "remarkably small", you don't need _any_ good engineering practices. You don't need encapsulation, abstraction, maintainability, anything. It's like killing an ant with a bazooka. Pretty much nothing you do in a 100 SLOC codebase matters unless it's a library, in which case the only important thing is the API.
 That makes as much sense to me as introducing a keyword to 
 protect a class from itself.
It the equivalent of building another house to give your new child its own room, when you can simply assign a room in the house that you already have.
That's the beauty of code, isn't it? Building another house is easy so why not? If in real life I could conjure a whole new house in less than a second for a child to live in, why wouldn't I???
Nov 02 2018
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 2 November 2018 at 11:50:05 UTC, Atila Neves wrote:
 On Thursday, 1 November 2018 at 18:30:33 UTC, 12345swordy wrote:
 On Thursday, 1 November 2018 at 17:58:34 UTC, Atila Neves 
 wrote:
 [...]
Not the point. We talking about encapsulating code which involves creation of another modules which always involved in creation of another file. Which is not always good solution if your code is remarkably small.
That wasn't my point either. My point is that if your code is "remarkably small", you don't need _any_ good engineering practices. You don't need encapsulation, abstraction, maintainability, anything. It's like killing an ant with a bazooka.
When I said, "small code" I wasn't referring to the entire program itself, I was referring to the code being encapsulated. -Alex
Nov 02 2018
prev sibling parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis 
wrote:
 If anything, many of us have been convinced of the opposite by 
 actually using D. The way that D treats private is pratical and 
 useful, and adding a way to further restrict access to member 
 variables of classes would just be a further complication to 
 the language with little to no pratical benefit.
Why doesn't D treat const, within a module, the same way it treats private? I'm mean, either we're all friends, or we're not - which is it? ------------- class Plane { // private const int MAX_SPEED = 1000; // // bummer, my friends below can't change MAX_SPEED - it's const. // let's think of a way to help our friends... // I know, let's remove const // After all, we're all friends here. // nothing outside the module can touch MAX_SPEED anyway.. // ..it's private afterall. private int MAX_SPEED = 1000; } void main() { import std.stdio; Plane p = new Plane(); p.MAX_SPEED = -1; // no..you shouldn't have done that. // const would have saved the day. // (in the same way, a properly protected 'private' could also save the day. writeln(p.MAX_SPEED); // you may never see this, as the plane is now crashing. }; ------------------
Oct 29 2018
parent Neia Neutuladh <neia ikeran.org> writes:
On Tue, 30 Oct 2018 06:49:38 +0000, unprotected-entity wrote:
 Why doesn't D treat const, within a module, the same way it treats
 private?
 
 I'm mean, either we're all friends, or we're not - which is it?
 
 -------------
 class Plane {
      // private const int MAX_SPEED = 1000;
      //
      // bummer, my friends below can't change MAX_SPEED - it's
 const.
const prevents *anything* from altering the value through that variable. const-correctness is orthogonal to encapsulation.
Oct 30 2018
prev sibling parent reply Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Monday, 29 October 2018 at 13:52:47 UTC, unprotected-entity 
wrote:
[...]
 But nobody seems willing to listen to those proposals.

 Doesn't affect me. I already have great programming languages 
 that already do what I want them to do.

 I'd like to 'play' with D. But when private actually means 
 public (inside a module), and when I the programmer have no 
 control over this (within a module), then, my interest in D 
 cannot be sustained.

 If you have a class in a module, and you have anything else in 
 that module, then the encapsulation of your class is 
 immediately suspect - and anyone reviewing your code has to go 
 looking to see exactly what you're doing - because what the 
 class says about it interface, is irrelevant.
I hear you and understand you, but personally I still prefer the D spec as it is in this regard, except for the confusing aspect that you shouldn’t `alias this` a private member; but that is rather a limitation of alias, not of encapsulation. Remember, the concept of encapsulation existed long before OO, arguably in a much stronger form. See the second half of https://forum.dlang.org/post/vjduytokawqtbvpslzpe forum.dlang.org; as you see, you are not the first to bring this up. I can recommend the video link at the bottom of that post.
Oct 29 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo wrote:
 I hear you and understand you, but personally I still prefer 
 the D spec as it is in this regard, except for the confusing 
 aspect that you shouldn’t `alias this` a private member; but 
 that is rather a limitation of alias, not of encapsulation.
If your were sitting on a plane that was running the following D code, you might think differently ;-) -------- class Plane { private static int MAX_SPEED = 1000; public void change_max_speed(int speed) { if(speed >= 1000) MAX_SPEED = speed; } } immutable Plane p = new Plane(); // god no! why aren't you using the public interface of the class for this! void SetMaxSpeed() { p.MAX_SPEED = -1; } void Bar() { SetMaxSpeed(); } // mmm...trouble is about to begin... void main() { import std.stdio; Bar(); // oohps. thanks D module. we're all going to die! // by the time you see this, it's too late for you, and your passengers. writeln(p.MAX_SPEED); }; -------
Oct 29 2018
next sibling parent reply Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Tuesday, 30 October 2018 at 00:01:18 UTC, unprotected-entity 
wrote:
 On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo 
 wrote:
 I hear you and understand you, but personally I still prefer 
 the D spec as it is in this regard, except for the confusing 
 aspect that you shouldn’t `alias this` a private member; but 
 that is rather a limitation of alias, not of encapsulation.
If your were sitting on a plane that was running the following D code, you might think differently ;-) -------- class Plane { private static int MAX_SPEED = 1000; public void change_max_speed(int speed) { if(speed >= 1000) MAX_SPEED = speed; } } immutable Plane p = new Plane(); // god no! why aren't you using the public interface of the class for this! void SetMaxSpeed() { p.MAX_SPEED = -1; } void Bar() { SetMaxSpeed(); } // mmm...trouble is about to begin... void main() { import std.stdio; Bar(); // oohps. thanks D module. we're all going to die! // by the time you see this, it's too late for you, and your passengers. writeln(p.MAX_SPEED); }; -------
:-) Why is MAX_SPEED mutable or even a runtime value, let alone signed? Anyway, every example you can come up with can be turned around and applied to a large class, that is, similar mistakes can be made within the class. But let's not repeat arguments. If you want to use OO in D you'll just have to flip a switch in your head that you don't put pieces of code that should be protected from each other in the same file. Just like you wouldn't put them in the same class in your current mindset. It's not all that different. There are advantages and disadvantages to each approach. D's approach makes sense: Why would you trust someone with access to a file not to change the classes in that file, like slip a friend in there for convenience? These things are much easier to catch in review if spread over different files. The off-limits file can even be write protected in the RCS. You don't even need to see that file, just the generated documentation of it. (Did you watch the video?)
Oct 30 2018
parent reply Atila Neves <atila.neves gmail.com> writes:
On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo wrote:
 On Tuesday, 30 October 2018 at 00:01:18 UTC, unprotected-entity 
 wrote:
 On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo 
 wrote:
 I hear you and understand you, but personally I still prefer 
 the D spec as it is in this regard, except for the confusing 
 aspect that you shouldn’t `alias this` a private member; but 
 that is rather a limitation of alias, not of encapsulation.
If your were sitting on a plane that was running the following D code, you might think differently ;-) -------- class Plane { private static int MAX_SPEED = 1000; public void change_max_speed(int speed) { if(speed >= 1000) MAX_SPEED = speed; } } immutable Plane p = new Plane(); // god no! why aren't you using the public interface of the class for this! void SetMaxSpeed() { p.MAX_SPEED = -1; } void Bar() { SetMaxSpeed(); } // mmm...trouble is about to begin... void main() { import std.stdio; Bar(); // oohps. thanks D module. we're all going to die! // by the time you see this, it's too late for you, and your passengers. writeln(p.MAX_SPEED); }; -------
:-) Why is MAX_SPEED mutable or even a runtime value, let alone signed?
Strictly my opinion below, but I believe wholeheartedly in this: Using unsigned integers for anything except bit patterns and talking to hardware is an open invitation to bugs. The C++ community has recognised this and admitted that using size_t everywhere in the STL was a mistake. "Ah, but I want type safety!". Uh-huh: ----------------- int[] ints; // indexing uses size_t, but... auto i = ints[-1]; // look ma, no errors or warnings! ----------------- The problem in D and C++ is that they inherit behaviour from C, and in this case the important part of that inheritance is that integers of different types convert implicitly to each other. There is *no* type-safety when using unsigned integers. And because bit-patterns and actual integers share the same type now, people will invariably do something "they're not supposed to" and perform arithmetic with these values and usually wrap around. It's not pretty and it's not fun to debug. I have literally lost count of how many bugs I've had to fix due to unsigned integers. `long` is large enough for anything you need, as Java has shown for 2 decades now. Friends don't let friends use unsigned types for counting.
Nov 01 2018
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/1/18 10:28 AM, Atila Neves wrote:
 On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo wrote:
 On Tuesday, 30 October 2018 at 00:01:18 UTC, unprotected-entity wrote:
 On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo wrote:
 I hear you and understand you, but personally I still prefer the D 
 spec as it is in this regard, except for the confusing aspect that 
 you shouldn’t `alias this` a private member; but that is rather a 
 limitation of alias, not of encapsulation.
If your were sitting on a plane that was running the following D code, you might think differently ;-) -------- class Plane {     private static int MAX_SPEED = 1000;     public void change_max_speed(int speed)     {         if(speed >= 1000)             MAX_SPEED = speed;     } } immutable Plane p = new Plane(); // god no! why aren't you using the public interface of the class for this! void SetMaxSpeed() { p.MAX_SPEED = -1; } void Bar() { SetMaxSpeed(); } // mmm...trouble is about to begin... void main() {     import std.stdio;     Bar(); // oohps. thanks D module. we're all going to die!     // by the time you see this, it's too late for you, and your passengers.     writeln(p.MAX_SPEED); }; -------
:-) Why is MAX_SPEED mutable or even a runtime value, let alone signed?
Strictly my opinion below, but I believe wholeheartedly in this: Using unsigned integers for anything except bit patterns and talking to hardware is an open invitation to bugs. The C++ community has recognised this and admitted that using size_t everywhere in the STL was a mistake. "Ah, but I want type safety!". Uh-huh: ----------------- int[] ints; // indexing uses size_t, but... auto i = ints[-1];  // look ma, no errors or warnings! -----------------
It should throw an error, but actually, negative indexing is allowed in D or C, just on pointers only. And thanks to 2s complement math, it actually does index the right value. Not saying this is preferable or good, just that it works, and does exactly what it should do, and what you expect it to do. Where one generally gets into trouble is not specifying a negative number where an unsigned one is expected, but when one is comparing signed and unsigned numbers. The implicit casting definitely can make things more confusing than necessary. It's why I generally will avoid negative numbers in comparisons as much as possible. I.e. instead of if(x - 5 > y), I'll do if(x > y + 5).
 The problem in D and C++ is that they inherit behaviour from C, and in 
 this case the important part of that inheritance is that integers of 
 different types convert implicitly to each other. There is *no* 
 type-safety when using unsigned integers. And because bit-patterns and 
 actual integers share the same type now, people will invariably do 
 something "they're not supposed to" and perform arithmetic with these 
 values and usually wrap around. It's not pretty and it's not fun to debug.
I can see both sides. For instance Swift strictly forbids using signed to unsigned implicit casts, and the result is quite verbose. I write lots of code to find I have to add in lots of `bitPattern` and `truncatingBitPattern` etc. for things that are trivially obviously correct. I find you develop a kind of numbness to it, where you reflexively add in your conversions without thinking about the consequences -- and you end up in the same place with worse-looking code. -Steve
Nov 01 2018
prev sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Thursday, 1 November 2018 at 14:28:27 UTC, Atila Neves wrote:
 On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo 
 wrote:
 On Tuesday, 30 October 2018 at 00:01:18 UTC, 
 unprotected-entity wrote:
 On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo 
 wrote:
 I hear you and understand you, but personally I still prefer 
 the D spec as it is in this regard, except for the confusing 
 aspect that you shouldn’t `alias this` a private member; but 
 that is rather a limitation of alias, not of encapsulation.
If your were sitting on a plane that was running the following D code, you might think differently ;-) -------- class Plane { private static int MAX_SPEED = 1000; public void change_max_speed(int speed) { if(speed >= 1000) MAX_SPEED = speed; } } immutable Plane p = new Plane(); // god no! why aren't you using the public interface of the class for this! void SetMaxSpeed() { p.MAX_SPEED = -1; } void Bar() { SetMaxSpeed(); } // mmm...trouble is about to begin... void main() { import std.stdio; Bar(); // oohps. thanks D module. we're all going to die! // by the time you see this, it's too late for you, and your passengers. writeln(p.MAX_SPEED); }; -------
:-) Why is MAX_SPEED mutable or even a runtime value, let alone signed?
Strictly my opinion below, but I believe wholeheartedly in this: Using unsigned integers for anything except bit patterns and talking to hardware is an open invitation to bugs. The C++ community has recognised this and admitted that using size_t everywhere in the STL was a mistake. "Ah, but I want type safety!". Uh-huh: ----------------- int[] ints; // indexing uses size_t, but... auto i = ints[-1]; // look ma, no errors or warnings! ----------------- The problem in D and C++ is that they inherit behaviour from C, and in this case the important part of that inheritance is that integers of different types convert implicitly to each other. There is *no* type-safety when using unsigned integers. And because bit-patterns and actual integers share the same type now, people will invariably do something "they're not supposed to" and perform arithmetic with these values and usually wrap around. It's not pretty and it's not fun to debug. I have literally lost count of how many bugs I've had to fix due to unsigned integers. `long` is large enough for anything you need, as Java has shown for 2 decades now. Friends don't let friends use unsigned types for counting.
My experience is exactly the opposite. I inherited a code base of ~200K lines of C written over 3 decades by several developers of varying skills. You can not imagine how many bugs I found thanks to replacing int and long by size_t and uint32_t/uint64_t. int i = 0; ints[--i]; // look ma, no errors or warnings! indeed with size_t i at least you get segfault or a bus error. The worst offense is using int on 64 bit machines when working on big datasets, overflows are really more common than people expect. When using unsigned, it requires indeed to be careful when interacting with other variable, but since when is sloppiness a virtue? The thing is, all the code that used int as a default was code that was not thought through concerning the range of values and limits of the used variables.
Nov 01 2018
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/1/18 2:46 PM, Patrick Schluter wrote:
 On Thursday, 1 November 2018 at 14:28:27 UTC, Atila Neves wrote:
 On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo wrote:
 On Tuesday, 30 October 2018 at 00:01:18 UTC, unprotected-entity wrote:
 On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo wrote:
 I hear you and understand you, but personally I still prefer the D 
 spec as it is in this regard, except for the confusing aspect that 
 you shouldn’t `alias this` a private member; but that is rather a 
 limitation of alias, not of encapsulation.
If your were sitting on a plane that was running the following D code, you might think differently ;-) -------- class Plane {     private static int MAX_SPEED = 1000;     public void change_max_speed(int speed)     {         if(speed >= 1000)             MAX_SPEED = speed;     } } immutable Plane p = new Plane(); // god no! why aren't you using the public interface of the class for this! void SetMaxSpeed() { p.MAX_SPEED = -1; } void Bar() { SetMaxSpeed(); } // mmm...trouble is about to begin... void main() {     import std.stdio;     Bar(); // oohps. thanks D module. we're all going to die!     // by the time you see this, it's too late for you, and your passengers.     writeln(p.MAX_SPEED); }; -------
:-) Why is MAX_SPEED mutable or even a runtime value, let alone signed?
Strictly my opinion below, but I believe wholeheartedly in this: Using unsigned integers for anything except bit patterns and talking to hardware is an open invitation to bugs. The C++ community has recognised this and admitted that using size_t everywhere in the STL was a mistake. "Ah, but I want type safety!". Uh-huh: ----------------- int[] ints; // indexing uses size_t, but... auto i = ints[-1];  // look ma, no errors or warnings! ----------------- The problem in D and C++ is that they inherit behaviour from C, and in this case the important part of that inheritance is that integers of different types convert implicitly to each other. There is *no* type-safety when using unsigned integers. And because bit-patterns and actual integers share the same type now, people will invariably do something "they're not supposed to" and perform arithmetic with these values and usually wrap around. It's not pretty and it's not fun to debug. I have literally lost count of how many bugs I've had to fix due to unsigned integers. `long` is large enough for anything you need, as Java has shown for 2 decades now. Friends don't let friends use unsigned types for counting.
My experience is exactly the opposite. I inherited a code base of ~200K lines of C written over 3 decades by several developers of varying skills. You can not imagine how many bugs I found thanks to replacing int and long by size_t and uint32_t/uint64_t. int i = 0; ints[--i];  // look ma, no errors or warnings! indeed with size_t i at least you get segfault or a bus error.
My testing looks like it's the same: #include <stdio.h> int main() { int arr[5]; int *ptr = arr + 1; // point at second element so we can do negative indexing legally int idx1 = 0; ptr[--idx1] = 5; printf("%d\n", arr[0]); // 5 size_t idx2 = 0; ptr[--idx2] = 6; printf("%d\n", arr[0]); // 6 return 0; } -Steve
Nov 01 2018
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 1 November 2018 at 19:26:05 UTC, Steven 
Schveighoffer wrote:
 My testing looks like it's the same:

 #include <stdio.h>
 int main()
 {
     int arr[5];
     int *ptr = arr + 1; // point at second element so we can do 
 negative indexing legally
     int idx1 = 0;
     ptr[--idx1] = 5;
     printf("%d\n", arr[0]); // 5
     size_t idx2 = 0;
     ptr[--idx2] = 6;
     printf("%d\n", arr[0]); // 6
     return 0;
 }

 -Steve
`ptr[--idx2]` is undefined behavior (out-of-bounds array access), so the fact that it works that way is just a coincidence.
Nov 01 2018
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/1/18 4:15 PM, Paul Backus wrote:
 On Thursday, 1 November 2018 at 19:26:05 UTC, Steven Schveighoffer wrote:
 My testing looks like it's the same:

 #include <stdio.h>
 int main()
 {
     int arr[5];
     int *ptr = arr + 1; // point at second element so we can do 
 negative indexing legally
     int idx1 = 0;
     ptr[--idx1] = 5;
     printf("%d\n", arr[0]); // 5
     size_t idx2 = 0;
     ptr[--idx2] = 6;
     printf("%d\n", arr[0]); // 6
     return 0;
 }
`ptr[--idx2]` is undefined behavior (out-of-bounds array access), so the fact that it works that way is just a coincidence.
Either way, I don't see it causing a segfault -- the purported benefit. But maybe on Patrick's actual arch it did. In any case, undefined behavior is bad whether you do it with an int or size_t :) -Steve
Nov 01 2018
prev sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Thursday, 1 November 2018 at 20:15:57 UTC, Paul Backus wrote:
 On Thursday, 1 November 2018 at 19:26:05 UTC, Steven 
 Schveighoffer wrote:
 My testing looks like it's the same:

 #include <stdio.h>
 int main()
 {
     int arr[5];
     int *ptr = arr + 1; // point at second element so we can 
 do negative indexing legally
     int idx1 = 0;
     ptr[--idx1] = 5;
     printf("%d\n", arr[0]); // 5
     size_t idx2 = 0;
     ptr[--idx2] = 6;
     printf("%d\n", arr[0]); // 6
     return 0;
 }

 -Steve
`ptr[--idx2]` is undefined behavior (out-of-bounds array access), so the fact that it works that way is just a coincidence.
It works also because the optimizer eludes the ptr accesses. So to test the example, at least put -O0. mov esi, 5 mov edi, OFFSET FLAT:.LC0 xor eax, eax call printf mov esi, 6 mov edi, OFFSET FLAT:.LC0 xor eax, eax call printf and in real life, the erroneaous accesses where I had the index underflowing the array were much more complicated and have not been found for decades. We had noticed sometimes that things were wrong in the documents processed, but it was impossible to trace back were the error was. After refactoring to use more agressively size_t a whole bunch of these glitchy glitches transformed into nice actionable debugable core dumps.
Nov 01 2018
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/1/18 5:03 PM, Patrick Schluter wrote:
 On Thursday, 1 November 2018 at 20:15:57 UTC, Paul Backus wrote:
 On Thursday, 1 November 2018 at 19:26:05 UTC, Steven Schveighoffer wrote:
 My testing looks like it's the same:

 #include <stdio.h>
 int main()
 {
     int arr[5];
     int *ptr = arr + 1; // point at second element so we can do 
 negative indexing legally
     int idx1 = 0;
     ptr[--idx1] = 5;
     printf("%d\n", arr[0]); // 5
     size_t idx2 = 0;
     ptr[--idx2] = 6;
     printf("%d\n", arr[0]); // 6
     return 0;
 }
`ptr[--idx2]` is undefined behavior (out-of-bounds array access), so the fact that it works that way is just a coincidence.
It works also because the optimizer eludes the ptr accesses. So to test the example, at least put -O0.         mov     esi, 5         mov     edi, OFFSET FLAT:.LC0         xor     eax, eax         call    printf         mov     esi, 6         mov     edi, OFFSET FLAT:.LC0         xor     eax, eax         call    printf
As I said, I didn't use optimizations. And I still didn't get any segfaults.
 
 and in real life, the erroneaous accesses where I had the index 
 underflowing the array were much more complicated and have not been 
 found for decades. We had noticed sometimes that things were wrong in 
 the documents processed, but it was impossible to trace back were the 
 error was. After refactoring to use more agressively size_t a whole 
 bunch of these glitchy glitches transformed into nice actionable 
 debugable core dumps.
Well, one thing that is very possible, is that if you use uint on a 64-bit system, you will get segfaults (potentially). -Steve
Nov 01 2018
prev sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Thursday, 1 November 2018 at 19:26:05 UTC, Steven 
Schveighoffer wrote:
 On 11/1/18 2:46 PM, Patrick Schluter wrote:
 [...]
My testing looks like it's the same: #include <stdio.h> int main() { int arr[5]; int *ptr = arr + 1; // point at second element so we can do negative indexing legally int idx1 = 0; ptr[--idx1] = 5; printf("%d\n", arr[0]); // 5 size_t idx2 = 0; ptr[--idx2] = 6; printf("%d\n", arr[0]); // 6 return 0; }
Compiled with -m64 ? On a 32 bit machine it makes indeed no difference as the effective calculated address is in any case modulo 2^32-1 (a + 2^32-1) % 2^32 == a-1
Nov 01 2018
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/1/18 4:47 PM, Patrick Schluter wrote:
 On Thursday, 1 November 2018 at 19:26:05 UTC, Steven Schveighoffer wrote:
 On 11/1/18 2:46 PM, Patrick Schluter wrote:
 [...]
My testing looks like it's the same: #include <stdio.h> int main() {     int arr[5];     int *ptr = arr + 1; // point at second element so we can do negative indexing legally     int idx1 = 0;     ptr[--idx1] = 5;     printf("%d\n", arr[0]); // 5     size_t idx2 = 0;     ptr[--idx2] = 6;     printf("%d\n", arr[0]); // 6     return 0; }
Compiled with -m64 ? On a 32 bit machine it makes indeed no difference as the effective calculated address is in any case modulo 2^32-1 (a + 2^32-1) % 2^32 == a-1
amd64 system (Intel Mac) I wouldn't be surprised if on other architectures, you get a bus error. -Steve
Nov 01 2018
parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Thursday, 1 November 2018 at 21:00:21 UTC, Steven 
Schveighoffer wrote:
 On 11/1/18 4:47 PM, Patrick Schluter wrote:
 On Thursday, 1 November 2018 at 19:26:05 UTC, Steven 
 Schveighoffer wrote:
[...]
Compiled with -m64 ? On a 32 bit machine it makes indeed no difference as the effective calculated address is in any case modulo 2^32-1 (a + 2^32-1) % 2^32 == a-1
amd64 system (Intel Mac) I wouldn't be surprised if on other architectures, you get a bus error.
the optimizer removed all the array code, in your example and only kept the printf with precalculated constants. In gcc and in clang.
Nov 01 2018
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/1/18 5:08 PM, Patrick Schluter wrote:
 On Thursday, 1 November 2018 at 21:00:21 UTC, Steven Schveighoffer wrote:
 On 11/1/18 4:47 PM, Patrick Schluter wrote:
 On Thursday, 1 November 2018 at 19:26:05 UTC, Steven Schveighoffer 
 wrote:
 [...]
Compiled with -m64 ? On a 32 bit machine it makes indeed no difference as the effective calculated address is in any case modulo 2^32-1 (a + 2^32-1) % 2^32 == a-1
amd64 system (Intel Mac) I wouldn't be surprised if on other architectures, you get a bus error.
the optimizer removed all the array code, in your example and only kept the printf with precalculated constants. In gcc and in clang.
Well, I didn't specify any optimizations, so I'm not sure that's the case. -Steve
Nov 01 2018
prev sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Thursday, 1 November 2018 at 18:46:37 UTC, Patrick Schluter 
wrote:
 On Thursday, 1 November 2018 at 14:28:27 UTC, Atila Neves wrote:
 On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo 
 wrote:
 On Tuesday, 30 October 2018 at 00:01:18 UTC, 
 unprotected-entity wrote:
 On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo 
 wrote:
 Friends don't let friends use unsigned types for counting.
My experience is exactly the opposite. I inherited a code base of ~200K lines of C written over 3 decades by several developers of varying skills. You can not imagine how many bugs I found thanks to replacing int and long by size_t and uint32_t/uint64_t. int i = 0; ints[--i]; // look ma, no errors or warnings! indeed with size_t i at least you get segfault or a bus error.
I'm interested in knowing how you don't get a segfault with a signed integer. I'm guessing a big block of pre-allocated memory?
 The worst offense is using int on 64 bit machines when working 
 on big datasets, overflows are really more common than people 
 expect.
The problem there is using `int`, not the fact that `int` is signed.
 When using unsigned, it requires indeed to be careful when 
 interacting with other variable, but since when is sloppiness a 
 virtue?
In programming? Laziness is always a virtue. If I wanted to be careful when I write code, I wouldn't be on this forum. Besides, even if *I'm* careful, my colleagues might not be, and it'll be me paying the gdb price.
 The thing is, all the code that used int as a default was code 
 that was not thought through concerning the range of values and 
 limits of the used variables.
I learned C using 16-bit Borland, which meant `int` was the same as `short`. Every time I wrote a for loop back then I had to consider if I needed `long` instead.
Nov 02 2018
parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Friday, 2 November 2018 at 12:00:05 UTC, Atila Neves wrote:
 On Thursday, 1 November 2018 at 18:46:37 UTC, Patrick Schluter 
 wrote:
 On Thursday, 1 November 2018 at 14:28:27 UTC, Atila Neves 
 wrote:
 On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo 
 wrote:
 On Tuesday, 30 October 2018 at 00:01:18 UTC, 
 unprotected-entity wrote:
 On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo 
 wrote:
 Friends don't let friends use unsigned types for counting.
My experience is exactly the opposite. I inherited a code base of ~200K lines of C written over 3 decades by several developers of varying skills. You can not imagine how many bugs I found thanks to replacing int and long by size_t and uint32_t/uint64_t. int i = 0; ints[--i]; // look ma, no errors or warnings! indeed with size_t i at least you get segfault or a bus error.
I'm interested in knowing how you don't get a segfault with a signed integer. I'm guessing a big block of pre-allocated memory?
We were talking C here. An array access to offset -1 only goes to the memory befor the array. If the array is on the stack it's another variable or the return address of the function. It it's in the heap, it's generally some overhead structure of the allocator or another buffer if the chunk of memory is from a slab allocator. Only when using tools like efence or valgrind that will allocate a memory page for every allocated block will it be possible to crash with a a[-1] access.
 The worst offense is using int on 64 bit machines when working 
 on big datasets, overflows are really more common than people 
 expect.
The problem there is using `int`, not the fact that `int` is signed.
True. Only 2 billion happens before 4 billion.
 When using unsigned, it requires indeed to be careful when 
 interacting with other variable, but since when is sloppiness 
 a virtue?
In programming? Laziness is always a virtue. If I wanted to be careful when I write code, I wouldn't be on this forum.
I didn't say laziness (pereza), but sloppiness (descuidado) it's not the same thing.
 Besides, even if *I'm* careful, my colleagues might not be, and 
 it'll be me paying the gdb price.

 The thing is, all the code that used int as a default was code 
 that was not thought through concerning the range of values 
 and limits of the used variables.
I learned C using 16-bit Borland, which meant `int` was the same as `short`. Every time I wrote a for loop back then I had to consider if I needed `long` instead.
Yeah, 16 bit Borland C was the horror if you had to work on far and huge memory model. The fun part was that size_t wouldn't have helped as it was only a unsigned int (if ever people wanted an example of a platform where sizeof(size_t ) < sizeof(long) real mode x86 is it).
Nov 02 2018
prev sibling parent reply ShadoLight <ettienne.gilbert gmail.com> writes:
On Tuesday, 30 October 2018 at 00:01:18 UTC, unprotected-entity 
wrote:
 On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo 
 wrote:

[snip]

 If your were sitting on a plane that was running the following 
 D code, you might think differently ;-)

 --------
 class Plane
 {
     private static int MAX_SPEED = 1000;

     public void change_max_speed(int speed)
     {
         if(speed >= 1000)
             MAX_SPEED = speed;
     }

 }

 immutable Plane p = new Plane();

 // god no! why aren't you using the public interface of the 
 class for this!
 void SetMaxSpeed() { p.MAX_SPEED = -1; }

 void Bar() { SetMaxSpeed(); } // mmm...trouble is about to 
 begin...

 void main()
 {
     import std.stdio;

     Bar(); // oohps. thanks D module. we're all going to die!

     // by the time you see this, it's too late for you, and 
 your passengers.
     writeln(p.MAX_SPEED);

 };


 -------
Cute example, but your proposed solution does not mitigate this risk either. Let's say D does indeed have your 'strict' definition of private w.r.t. encapsulation. So, with your definition this program will fail to compile, but remember that Joe Coder is actually modifying the module i.e. he has access to the source code of class Plane.... so now he does this: class Plane { private static int MAX_SPEED = 1000; public void change_max_speed(int speed) { if(speed >= 1000) MAX_SPEED = speed; } // Man, I need to get this finshed; have a movie date with Sally! public void SetMaxSpeed() { MAX_SPEED = -1; } } immutable Plane p = new Plane(); void Bar() { p.SetMaxSpeed(); } // mmm...trouble is about to begin... void main() { import std.stdio; Bar(); // oohps. thanks D module. we're all going to die! // by the time you see this, it's too late for you, and your passengers. writeln(p.MAX_SPEED); }; Note this is all contained to the same module... so quite easy for Joe Coder to make _any_change_whatsoever_! If you want to avoid this risk you have to encapsulate (even in your case) at the module level, and only allow access via the API (maybe not even allow access to sources of class Plane and link to a critical_resources.LIB/DLL). The point is that you cannot completely mitigate against this type of risk, no matter what form of encapsulation you may have, when people have access to all the sources. Hence the need for code reviews, unit tests, etc, etc. There are always areas where languages have "back doors" (or lets call them doors with weaker locks). At this point this threat are really arguing about a personal preferences; it is not a black or white affair.
Oct 30 2018
parent unprotected-entity <unprotected-entity gmail.com> writes:
On Tuesday, 30 October 2018 at 09:43:54 UTC, ShadoLight wrote:
 At this point this threat are really  arguing about a personal 
 preferences; it is not a black or white affair.
Yes, true, sort of. The problem as I see it, is that D does not even give you (me) the option to implement such my preference - which is to declare a private member of a class within a module, and have the guarantee (by the compiler) that other code my module does not directly touch it. It's not a big ask really. It's what I already It doesn't mean changing what private means. But it could, rather easily, mean adding some syntax that would allow me to clearly declare my intentions (such as: strict private - as freepascal do it ( I made a post about this, but my posts are not being put up for some reason - maybe the person who does that thing is asleep or whatever. I can't have a conversation under those conditions (i.e. where some person, somewhere, at some random time, decides whether posts should be displayed - if they get around to it that is..), so I'm not going to bother wasting any more time with this matter. I just got new xbox one x, and rdr2 - so I'm attention will be elsewhere, for some time .....
Oct 30 2018
prev sibling next sibling parent unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 10:32:00 UTC, Mike Parker wrote:
 I don't think I've ever heard of anyone speak of encapsulation 
 in terms of function scopes and anonymous scopes. That's a 
 fairly narrow definition. At any rate, I don't put variables 
 inside a function to keep them out of the public API.
How is that a narrow definition on encapsulation? A function hides distracting details, and exposes a simple interface to its client. What goes on inside, is mostly irrelevant to the client, as long as it does what it's meant to do. Typically, you can go and change how it does it, without affecting the client. That's encapsulation..surely. The argument is a little harder to make for an anonymous scope, I give you that, but it also can have encapsulating properties in any case. There should never really be any need to get at the interior of a function, outside of that function? Use it's interface. That's why it's there. I'm just making the same case for classes. structs on the otherhand, well ... do what you want with 'em ;-)
Oct 29 2018
prev sibling next sibling parent unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 10:32:00 UTC, Mike Parker wrote:
 I can't speak for others, but it's a feature I use fairly 
 often. I tend to design aggregates and free functions to the 
 module, as a cohesive whole, rather than as separate parts. If 
 I want separate parts, I put them in different modules and use 
 `package` for the bits that need to stay out of the public API. 
 Works a treat.
Well, I think I've dicussed this enough. I point you all to this link, that has essentially what I'm asking for in D. "'www.freepascal.org/docs-html/ref/refse34.html'" Something like their 'strict private' would really be an advantage to D. And.. not a single response, so far, has reasonably demonstated, that giving this option to the programmer, would negatively affect the perception or use of D. I rest my case.
Oct 30 2018
prev sibling parent Guillaume Piolat <spam smam.org> writes:
On Monday, 29 October 2018 at 10:32:00 UTC, Mike Parker wrote:
 I can't speak for others, but it's a feature I use fairly 
 often. I tend to design aggregates and free functions to the 
 module, as a cohesive whole, rather than as separate parts. If 
 I want separate parts, I put them in different modules and use 
 `package` for the bits that need to stay out of the public API. 
 Works a treat.
+1 I also see how it could be a problem in a team. There is a tension between features for a team with "shared ownership of code" and features for individual developers. Perhaps there is way to do a "Voldemort member", something that can't be named outside of the class.
Nov 05 2018
prev sibling parent reply Zot <Zot Zot.Zot> writes:
On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity 
wrote:
 Just how often does one need to access the private members of a 
 class, within a module?
a lot actually. e.g. unittests
Oct 31 2018
next sibling parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote:
 On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity 
 wrote:
 Just how often does one need to access the private members of 
 a class, within a module?
a lot actually. e.g. unittests
that does not compute. all you are doing is further coupling unit-tests, with all the other crap that is already coupled in your module. Too many programmers these days, have no concept of clean architecture. You should be find ways to further decouple your code, not finding even more ways to further couple it. Since, in D, there is no concept of encapsulation, or information hiding, *within* a module, it (sadly) promotes the wrong type of architecture, by default. The module is just a convenient hack to avoid thinking about decoupling. Everything could dependent on everything else in your module - you have to read the whole 10,000 lines to discover what it's all about..(that's how much of phobos is designed, it seems). It's C like programming, masquerading as modern software design. if you want to test something that is private, call its public interface. that seems a pretty sensible guideline to me. and why is it so hard to put the unit test inside the actual class? that too seems like a pretty sensible guidline, to me. many on this forum have said, that the amount of code in your module should be fairly minimal (especially if you take the one class per module concept seriously). of course, in practice, that is not what happens - just look at phobos. the module should be a grouping of related functionality. that doesn't mean it should have no concept of encapsulation of information hiding within it - that will only lead to bad design. --------------- module test; class Test { private int Value; unittest { Test t = new Test(); assert(t.Value == 10); } } ----------------
Oct 31 2018
parent Neia Neutuladh <neia ikeran.org> writes:
On Thu, 01 Nov 2018 02:44:47 +0000, unprotected-entity wrote:
 On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote:
 On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity wrote:
 Just how often does one need to access the private members of a class,
 within a module?
a lot actually. e.g. unittests
that does not compute. all you are doing is further coupling unit-tests, with all the other crap that is already coupled in your module.
If I'm writing larger-scale tests, I want them to be durable to code changes; those tests are about exercising the code in the same way as a consumer of my library would. The types of tests I'm writing that might need access to private members are generally pretty short and focused, and they don't test the library as I expect consumers to use it. They're likely to be testing a private function opaquely, not examining private variables in a class. And if I change the function, I probably need to change the tests.
 and why is it so hard to put the unit test inside the actual class?
class Foo(T) { unittest {} } That test might never get run with `dub test`, and it's going to get compiled into every instantiation of the type in every consumer of my library. That's kinda bad. There *is* a workaround. Where you would write: class Foo(T) { } unittest { new Foo!int; } You instead write: class Foo(T) { version (MyLibraryTest) static if (is(T == int)) unittest { new Foo; } } version (MyLibraryTest) unittest { // force the template to instantiate Foo!int f; } That's a lot easier to mess up, so I'd rather use the short version.
Oct 31 2018
prev sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote:
 On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity 
 wrote:
 Just how often does one need to access the private members of 
 a class, within a module?
a lot actually. e.g. unittests
Unit tests should go through the public interface like anyone else. All private members and functions are implementation details that shouldn't matter and shouldn't break any tests if they're all removed.
Nov 01 2018
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/1/18 10:29 AM, Atila Neves wrote:
 On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote:
 On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity wrote:
 Just how often does one need to access the private members of a 
 class, within a module?
a lot actually. e.g. unittests
Unit tests should go through the public interface like anyone else. All private members and functions are implementation details that shouldn't matter and shouldn't break any tests if they're all removed.
So... don't test private functions? I do all the time. I want to test every single function I can. I also look at internals, especially when I find bugs about them that can be caught with a peek at internal data. Perhaps the internals implement some protocol, and you want to check it's in the right state part-way through a transaction. However, I would *love* to be able to specify unit tests that *can't* access private internals for testing purposes. IIRC, it was proposed at some point to require this for documented unittests. -Steve
Nov 01 2018
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Nov 01, 2018 at 01:59:35PM -0400, Steven Schveighoffer via
Digitalmars-d wrote:
 On 11/1/18 10:29 AM, Atila Neves wrote:
[...]
 Unit tests should go through the public interface like anyone else.
 All private members and functions are implementation details that
 shouldn't matter and shouldn't break any tests if they're all
 removed.
So... don't test private functions? I do all the time. I want to test every single function I can.
Exactly. There's value to white-box testing. For one thing, it allows you to guard yourself against regressions in implementation details that would otherwise be hard or infeasible to test from outside. But black-box testing is also needed, e.g., to specify expected external behaviours that should not break when the implementation details change. IMO, we should have both. [...]
 However, I would *love* to be able to specify unit tests that *can't*
 access private internals for testing purposes. IIRC, it was proposed
 at some point to require this for documented unittests.
[...] That's a good idea. Nothing is worse than documentation that references private members, that you copy-n-paste only to find that you can't write the code that way. Also, for proper black-box testing, it would be nice to have the assurance that it's actually specifying outside-observable behaviour rather than implementation details. The two seem related, though. If a unittest test tests outside behaviour, chances are it should be a ddoc'd unittest too, so that users know what the expected outside behaviour is. Perhaps it makes sense to conflate the two, so you could specify a black-box test just by attaching a ddoc comment to it. T -- Elegant or ugly code as well as fine or rude sentences have something in common: they don't depend on the language. -- Luca De Vitis
Nov 01 2018
prev sibling next sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Thursday, 1 November 2018 at 17:59:35 UTC, Steven 
Schveighoffer wrote:
 On 11/1/18 10:29 AM, Atila Neves wrote:
 On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote:
 On Monday, 29 October 2018 at 09:25:07 UTC, 
 unprotected-entity wrote:
 Just how often does one need to access the private members 
 of a class, within a module?
a lot actually. e.g. unittests
Unit tests should go through the public interface like anyone else. All private members and functions are implementation details that shouldn't matter and shouldn't break any tests if they're all removed.
So... don't test private functions?
Precisely. Caveat: test them if you *really* want to, but be prepared to delete the tests with extreme prejudice. I never do, implementation details are just that.
 I do all the time. I want to test every single function I can.
Testing to me is like going to the gym. I don't actually want to do it, but I do anyway because the alternative is worse. IMHO, tests take time to write, and testing implementation details is not a worthwhile use of my time.
 I also look at internals, especially when I find bugs about 
 them that can be caught with a peek at internal data.
Sure, but that's not what my point was.
 Perhaps the internals implement some protocol, and you want to 
 check it's in the right state part-way through a transaction.
If you're writing it from scratch, I'd say write a test for that as you're going. But then delete it after you're done. If it's already written I'd use a debugger.
 However, I would *love* to be able to specify unit tests that 
 *can't* access private internals for testing purposes. IIRC, it 
 was proposed at some point to require this for documented 
 unittests.
I do this all the time by having the tests in a different file, which is what I always do now given how much trouble in-module unittests have been for me.
Nov 02 2018
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Friday, 2 November 2018 at 11:43:13 UTC, Atila Neves wrote:
 On Thursday, 1 November 2018 at 17:59:35 UTC, Steven 
 Schveighoffer wrote:
 So... don't test private functions?
Precisely. Caveat: test them if you *really* want to, but be prepared to delete the tests with extreme prejudice. I never do, implementation details are just that.
Sometimes you need to, even if you don't want to. Say you're implementing a container, for simplicity let's say an Array!T (akin to Vector from your automem library). Because it's D, the author needs to be aware of GC implications. Namely, when removing elements from the array, or reserving additional storage, and `T` may have indirections, the Array should wipe unused storage (or appropriate bits) to eliminate false pointers. This isn't a part of public interface at all, but still something that should be tested against.
Nov 02 2018
parent Atila Neves <atila.neves gmail.com> writes:
On Friday, 2 November 2018 at 12:53:44 UTC, Stanislav Blinov 
wrote:
 On Friday, 2 November 2018 at 11:43:13 UTC, Atila Neves wrote:
 On Thursday, 1 November 2018 at 17:59:35 UTC, Steven 
 Schveighoffer wrote:
 So... don't test private functions?
Precisely. Caveat: test them if you *really* want to, but be prepared to delete the tests with extreme prejudice. I never do, implementation details are just that.
Sometimes you need to, even if you don't want to. Say you're implementing a container, for simplicity let's say an Array!T (akin to Vector from your automem library). Because it's D, the author needs to be aware of GC implications. Namely, when removing elements from the array, or reserving additional storage, and `T` may have indirections, the Array should wipe unused storage (or appropriate bits) to eliminate false pointers. This isn't a part of public interface at all, but still something that should be tested against.
This is more a comment on the lack of druntime's lack of testability than anything else. I'm still annoyed (and slightly worried) that I can't test that I'm telling the GC what I'm supposed to.
Nov 05 2018
prev sibling parent reply Q. F. Schroll <qs.il.paperinik gmail.com> writes:
On Thursday, 1 November 2018 at 17:59:35 UTC, Steven 
Schveighoffer wrote:
 However, I would *love* to be able to specify unit tests that 
 *can't* access private internals for testing purposes. IIRC, it 
 was proposed at some point to require this for documented 
 unittests.
How about public and private unittest? As a unittest is not a symbol, public and private cannot apply in the usual manner. In that context, a public unittest -- even in the same module -- is meant to test the public interface of something and therefore cannot access private state. A private (the default) unittest, on the other hand, tests private state. As another consequence, public (and private) with colon or braces do not apply to unittest; unittests must be marked directly. We could introduce "public unittest:" or even require syntactically that public (and private) are written after "unittest", i.e. "unittest public { ... }" to reduce confusion with visibility attributes. I once whished for that feature, too, and forgot about it.
Nov 02 2018
parent theoutlaw <theoutlaw hotmail.com> writes:
On Friday, 2 November 2018 at 15:18:05 UTC, Q. F. Schroll wrote:
 How about public and private unittest?

 ...A private ...unittest, on the other hand, tests private 
 state....
The problem is, that there is NO private state within a module. Not even for struct. Zilch! nəTHiNG! Now, how many who want private state for their struct type, are going to go down the path of putting 'one struct per module'. But those of us who want it for a class, are told to do just that. If only the programmer had a tool to define accessibility for a type, that would apply to accessibilty not just for code outside the module, but also to code within the module (but outside of that declared type), then: ------------- class Test { __private int Value; } unittest { T t = new T(); t.Value++; // No. it's private - so not accessible outside of the module. // No. it's also __private - so not accessible outside the type } ------------ Anyone who argues that this syntax would make the language too complex, and therefore we should avoid any further discussion, cannot be take seriously. On the otherhand, whether the actual implementation of such a feature, is doable, and workable with the language as a whole, I wouldn't know - and that is worth a discussion.
Nov 02 2018
prev sibling parent unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 06:15:25 UTC, Mike Parker wrote:
 Anyway, I'm not the one who needs convincing. And I have a high 
 degree of confidence that the ones who do need convincing won't 
 be. There has yet to be a strong enough argument to change this 
 behavior.
If anything, someone should be trying to convince me, to use D ;-) I do not believe, that a case can be made, to alter the status quo (if for no other reason, than to ensure existing code, keeps working). Howver, I have seen, on many occassions now, where this issue has popped up, along with ideas on how to possibly solve it. On each occassion, the idea gets put to rest very quickly, by some, one way or another. I think that is a real shame. A way to make a class member private, within a module, is an idea worthy of consideration, and has immediate practical value, both in terms of convincing people to use D, and also in better guarantees around the correctness of your code. The only argument for dismissing these ideas, when they pop up, seems to be, that nobody would ever be able to convince Walter/Andrei.. so why bother pursuing it any further. They are the stewards of the language, I get it, but I think that's a sad state of affairs. Inside a module, a private member of a class is a good, useful, practical construct (and I thought D was practical?).
Oct 29 2018
prev sibling next sibling parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Monday, 29 October 2018 at 05:13:22 UTC, unprotected-entity 
wrote:
 On Sunday, 28 October 2018 at 11:32:07 UTC, Mike Parker wrote:
 In D, the module is the unit of encapsulation, not the class.
That is not entirely correct. --- module test; import std.stdio; void test() { int a; } void main() { writeln(a); } // Error: undefined identifier 'a' --- The D module still considers a function to be it's own unit of encapsulation. Classes no longer have that status in D.
Yes they do. --- module test; import std.stdio; class C { int a; } void main() { writeln(a); } // Error: undefined identifier 'a'
Oct 29 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 08:34:39 UTC, FeepingCreature wrote:
 Yes they do.
 ---
 module test;
 import std.stdio;
 class C { int a; }
 void main() { writeln(a); } // Error: undefined identifier 'a'
Sorry, but you are wrong. Why? Because 'a' is nothing - it does not even exist. Not anywhere. To make it exist, you need to instantiate an object of C. Once it actually 'exists', you can do whatever you like with it, in the module, regardless of its access modifier. That means, quite simply, that the class is not a unit of encapsulation - within the module. Outside the module it is, but inside, it is not. That is just fact. It's not something we should be arguing about - cause it's just a fact. On the otherhand, a function (unlike a class) within a module, still retains it's encapsulating properties. i.e. void test() {int a;}; void main() {a++;}; // Error: undefined identifier 'a' - but this time, 'a' does exist - it's just that its correctly encapsulated in the function. Just imagine if a function did not have those encapsulating properties. Now, just imagine if a class did not (well, you don't need to imagine it ;-) I'm not trying to argue here. I'm just trying to clarify a fact, that some seem unable, or unwilling, to accept.
Oct 29 2018
next sibling parent biozic <dransic gmail.com> writes:
On Monday, 29 October 2018 at 09:15:35 UTC, unprotected-entity 
wrote:
 On Monday, 29 October 2018 at 08:34:39 UTC, FeepingCreature 
 wrote:
 Yes they do.
 ---
 module test;
 import std.stdio;
 class C { int a; }
 void main() { writeln(a); } // Error: undefined identifier 'a'
Sorry, but you are wrong. Why? Because 'a' is nothing - it does not even exist. Not anywhere.
Yes, it does exist as a symbol : --- import std.stdio; class C { int a; } void main() { writeln(typeof(C.a).stringof); } ---
 To make it exist, you need to instantiate an object of C.
No, see code above. Of course you would need to instantiate C to *use* it. But you would also need to call your test function to use its variable a.
 Once it actually 'exists', you can do whatever you like with 
 it, in the module, regardless of its access modifier. That 
 means, quite simply, that the class is not a unit of 
 encapsulation - within the module. Outside the module it is, 
 but inside, it is not.
Yes, exactly. These are the official D rules.
 That is just fact. It's not something we should be arguing 
 about - cause it's just a fact.

 On the otherhand, a function (unlike a class) within a module, 
 still retains it's encapsulating properties.

 i.e.
 void test() {int a;};
 void main() {a++;}; // Error: undefined identifier 'a' - but 
 this time, 'a' does exist - it's just that its correctly 
 encapsulated in the function.
You're confusing the existence a symbol and the path to access it. While there is a way to point to the field name 'a' in class 'C' in the code above (i.e `C.a`), there is no way to point to the variable 'a' in function test. So these are not encapsulation differences. Encapsulation is about whether or not you can use a symbol that you can point to with the correct syntax in the first place.
 Just imagine if a function did not have those encapsulating 
 properties.

 Now, just imagine if a class did not (well, you don't need to 
 imagine it ;-)

 I'm not trying to argue here. I'm just trying to clarify a 
 fact, that some seem unable, or unwilling, to accept.
Not clarified for me ;) Though I agree with you that there could be a `class private` access modifier in D for your use case.
Oct 29 2018
prev sibling parent FeepingCreature <feepingcreature gmail.com> writes:
On Monday, 29 October 2018 at 09:15:35 UTC, unprotected-entity 
wrote:
 On Monday, 29 October 2018 at 08:34:39 UTC, FeepingCreature 
 wrote:
 Yes they do.
 ---
 module test;
 import std.stdio;
 class C { int a; }
 void main() { writeln(a); } // Error: undefined identifier 'a'
Sorry, but you are wrong. Why? Because 'a' is nothing - it does not even exist. Not anywhere. To make it exist, you need to instantiate an object of C. Once it actually 'exists', you can do whatever you like with it, in the module, regardless of its access modifier. That means, quite simply, that the class is not a unit of encapsulation - within the module. Outside the module it is, but inside, it is not. That is just fact. It's not something we should be arguing about - cause it's just a fact. On the otherhand, a function (unlike a class) within a module, still retains it's encapsulating properties. i.e. void test() {int a;}; void main() {a++;}; // Error: undefined identifier 'a' - but this time, 'a' does exist - it's just that its correctly encapsulated in the function. Just imagine if a function did not have those encapsulating properties. Now, just imagine if a class did not (well, you don't need to imagine it ;-) I'm not trying to argue here. I'm just trying to clarify a fact, that some seem unable, or unwilling, to accept.
You are straight up factually mistaken about how functions work. void test() { int a; } <- this a does not exist *any* more than the a in class { int a; } does. It's only actually allocated once test is called, just like the a in the class is only allocated once the class is instantiated.
Oct 29 2018
prev sibling parent reply Neia Neutuladh <neia ikeran.org> writes:
On Mon, 29 Oct 2018 05:13:22 +0000, unprotected-entity wrote:
 I wonder if that would still be the case, if millions and millions of

 by accident, or by some obscure bug in their code), that a class is not
 considered a unit of encapsulation anymore.
should do the exact same as they do, your request is inconsistent and therefore unsatisfiable. I think this is the third time I've pointed it out.
 I think Go and Rust have done it better, somewhat, in that they don't
 even have classes. So you are forced to rethink your design anyway (if
 you want to use those languages)
Go and Rust use `private` the same as D. Shouldn't we cater to programmers familiar with those languages by making `private` work like they expect?
 Yes, there are situations in which it might be useful, I get it. But
 surely not every situation?
Which is why Swift has five different protection levels (but it skipped `protected` for some reason). That's a bit more complexity than I think is warranted.
Oct 29 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Monday, 29 October 2018 at 15:44:15 UTC, Neia Neutuladh wrote:

 saying we should do the exact same as they do, your request is 
 inconsistent and therefore unsatisfiable.

 I think this is the third time I've pointed it out.
what 'point' is that. can you 'point' it out again for me, cause I'm not clear what the 'point' of your 'point' is. btw. It's interesting, how a discussion on this matter *always* ends up with posts using a tone similar to where you are now going. i.e. it diverts more and more towards the personal, when people disagree with you.
Oct 29 2018
parent reply Neia Neutuladh <neia ikeran.org> writes:
On Mon, 29 Oct 2018 23:16:52 +0000, unprotected-entity wrote:
 On Monday, 29 October 2018 at 15:44:15 UTC, Neia Neutuladh wrote:

 we should do the exact same as they do, your request is inconsistent
 and therefore unsatisfiable.

 I think this is the third time I've pointed it out.
what 'point' is that. can you 'point' it out again for me, cause I'm not clear what the 'point' of your 'point' is.
consistent because they work differently from each other. Do you want to make things work like C++? Then you'll need to add a notion of friends. Do you want to make things work like Java? If you stick with Java-style coding with everything in a type and only one top-level type per module, that's what we have now. `private`, no notion of private-to-source-file or private-to-package, and a notion of private-to-compilation-unit. When you say "people will expect this to work like these three other languages" and those other languages do that thing differently from each other, it's hard to take your claims seriously.
 btw. It's interesting, how a discussion on this matter *always* ends up
 with posts using a tone similar to where you are now going.

 i.e. it diverts more and more towards the personal, when people disagree
 with you.
I exercise patience at the start, and it wears thin when people repeatedly ignore me.
Oct 29 2018
parent reply unprotected-entity <unprotected-entity gmail.com> writes:
On Tuesday, 30 October 2018 at 01:33:50 UTC, Neia Neutuladh wrote:

 C++ isn't consistent because they work differently from each 
 other.
I've already demonstrated that they all work the same: see: https://forum.dlang.org/post/dyfnrbjggqzianfwgvll forum.dlang.org And I don't want private in D to mean anything other than what it currently means - as that would be a breaking change, that could never be acceptable. On the otherhand, I have see ideas/propsals presented that do not really involve complexity, do not change what private means, but still provides an option to the programmer to better encapsulate their class, inside a module, from other code also in that module. I don't think that is so bad an idea, as to be completely dismissed.
 Do you want to make things work like C++? Then you'll need to 
 add a notion of friends.
No you don't. Stuff inside a module are already friends - they can do whatever they want to each other. Hopefully, the line the crashes your plane, is not on line 10,001 (cause you might not see that it's bypassing the interface of your class declared 9000 lines above it. I don't want more friendship, I want less (inside a module that is). And, I am specifically referring to classes, not structs. (although presumably it would be easy enought to accomodate a change to both. A such would have no effect outside of the module. So it's all back in the control of the programmer, rather than the language. btw. here is an interesting paper on 'friends' - well worth reading.
 When you say "people will expect this to work like these three 
 other languages" and those other languages do that thing 
 differently from each other, it's hard to take your claims 
 seriously.
really? when I looked at D, I expected the notion of private, declared within a class, to be private to that class (no matter what else is in the module). reasonable expectation for someone looking at using D. Is it not? (unless you intentionally try to override that - with, for example, a friend). In D, that overriding happens for you, automatically, within a module, and you get no say in it... whatsoever. And I know for a fact, that I am not the only one who expected that private declared within a class, to mean what it means in So I cannot take your claim (that such expectations do not exist) seriously.
 I exercise patience at the start, and it wears thin when people 
 repeatedly ignore me.
You starting to sound like that guy that runs the linux kernel project.. I believe he's just take time off to deal with that attitude...
Oct 29 2018
parent reply Neia Neutuladh <neia ikeran.org> writes:
On Tue, 30 Oct 2018 06:44:10 +0000, unprotected-entity wrote:
 On Tuesday, 30 October 2018 at 01:33:50 UTC, Neia Neutuladh wrote:

 isn't consistent because they work differently from each other.
I've already demonstrated that they all work the same:
I just pointed out ways in which they don't work the same. Let's add in some code to help out: C++: --- class C { private int i; friend void foo(); }; void foo() { C c; c.i = 10; } --- Also C++: --- class C { class CA { void foo() { CB b; // access error b.j++; C c; // works fine c.i++; } }; class CB { private: int j; }; private: int i; }; --- In C++, you can access private variables in your containing class (and its retaining class recursively), but not in other classes it contains. Java: --- public class C { private int i; public class Nested { private int j; } public class Nested2 { public void foo(Nested n, C c) { n.j++; c.i++; } } } --- In Java, protections apply to the outermost nested class. You can access anything that any enclosing or nested class can access. to a DLL, or you can make it private to exactly one type (and none of its nested types or parent types).
 btw. here is an interesting paper on 'friends' - well worth reading.
You didn't include a link.
 When you say "people will expect this to work like these three other
 languages" and those other languages do that thing differently from
 each other, it's hard to take your claims seriously.
really? when I looked at D, I expected the notion of private, declared within a class, to be private to that class (no matter what else is in the module). reasonable expectation for someone looking at using D. Is it not?
attributes, so saying you want something that satisfies people's actual objective. I also did a survey of like 14 different programming languages to see what they did, and there is very little consistency. So why do you want C++, instead of people coming from some other set of languages?
 In D, that overriding happens for you, automatically, within a module,
 and you get no say in it... whatsoever.
Aside from using more modules.
 I exercise patience at the start, and it wears thin when people
 repeatedly ignore me.
You starting to sound like that guy that runs the linux kernel project.. I believe he's just take time off to deal with that attitude...
If you want people to change how they communicate with you, it might benefit you to consider how to accomplish that. Trying to call someone an asshole on the sly doesn't seem like an effective way to improve their attitudes toward you.
Oct 30 2018
parent aliak <something something.com> writes:
On Tuesday, 30 October 2018 at 15:12:50 UTC, Neia Neutuladh wrote:
 On Tue, 30 Oct 2018 06:44:10 +0000, unprotected-entity wrote:
 [...]
I just pointed out ways in which they don't work the same. Let's add in some code to help out: C++: --- class C { private int i; friend void foo(); }; void foo() { C c; c.i = 10; } --- Also C++: --- class C { class CA { void foo() { CB b; // access error b.j++; C c; // works fine c.i++; } }; class CB { private: int j; }; private: int i; }; --- In C++, you can access private variables in your containing class (and its retaining class recursively), but not in other classes it contains. Java: --- public class C { private int i; public class Nested { private int j; } public class Nested2 { public void foo(Nested n, C c) { n.j++; c.i++; } } } --- In Java, protections apply to the outermost nested class. You can access anything that any enclosing or nested class can access. something private to a DLL, or you can make it private to exactly one type (and none of its nested types or parent types).
 [...]
You didn't include a link.
 [...]
protection attributes, so saying you want something that satisfies people's expectations when they're coming from C++, I also did a survey of like 14 different programming languages to see what they did, and there is very little consistency. So with D's protection attributes instead of people coming from some other set of languages?
 [...]
Aside from using more modules.
 [...]
If you want people to change how they communicate with you, it might benefit you to consider how to accomplish that. Trying to call someone an asshole on the sly doesn't seem like an effective way to improve their attitudes toward you.
He's talking about private in general meaning that something is accessible within the scope it's declared in. Which "in general" is what private means, obviously some languages have caveats, and Kotlin, all use private in a class to mean "this variable is only accessible from the scope of this class" where the definition of scope varies (as you have pointed out) between languages. And that is quite consistent. Rust doesn't have a keyword called private AFAIK. Cheers, - Ali
Oct 30 2018
prev sibling parent reply Danni Coy <danni.coy gmail.com> writes:
On Sun, Oct 28, 2018 at 9:30 PM unprotected-entity via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 On Sunday, 28 October 2018 at 05:28:31 UTC, Mike Parker wrote:
 You can make the same mistake inside the class:

 class Foo {
    private int x;
    void increment() {...}
    ...
    void doSomethingInternal() { x++; }
 }

 How is making that mistake outside of that final curly brace
 any different or any worse? It's all in the same file.
Except, that (I assume) a module in D is meant to be more than just a single class. If that's not the case, then my argument is irrelevant. If it is the case, then you presumably would have a great deal more code in your module, than you would in a single class. Hence, greater likelihood of mistakingly accessing a private member of some class defined within the module, somewhere. In any case, it does undermine the principle of encapsulation (assuming you agree that a class deserves to be a unit of encapsulation). In, it's nothing more than a convenient hack, really. There is not a third option here. The advantage of the Way D does things is that you don't have to put your
data into a class and instantiate it in order to have encapsulation. In C++ for instance often data is put into a class just to have encapsulation, this has a cost in resources as well the complexity of program. In D any data that there only needs to be one copy of and lasts the lifetime of the program belongs in a module rather than a class. In practice this tends to mean less classes, and less of the work done inside classes. D source code can feel inside out compared to C++ source code.
Oct 28 2018
parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Monday, 29 October 2018 at 00:36:43 UTC, Danni Coy wrote:
 On Sun, Oct 28, 2018 at 9:30 PM unprotected-entity via 
 Digitalmars-d < digitalmars-d puremagic.com> wrote:

 [...]
data into a class and instantiate it in order to have encapsulation. In C++ for instance often data is put into a class just to have encapsulation, this has a cost in resources as well the complexity of program. In D any data that there only needs to be one copy of and lasts the lifetime of the program belongs in a module rather than a class. In practice this tends to mean less classes, and less of the work done inside classes. D source code can feel inside out compared to C++ source code.
No need for complicated singleton pattern in D.
Oct 29 2018
prev sibling parent reply Neia Neutuladh <neia ikeran.org> writes:
On Sun, 28 Oct 2018 04:38:53 +0000, unprotected-entity wrote:

 declared private to C.
Let's look at a few languages and see exactly what they do. In C++, x is private to C and any friend types or functions. In D, x is private to C and any types or functions defined in the same module. In Dart, _x is private to C. In Delphi, x is private to C. In Go, x is private to that source file. (I believe. It might be private to that directory. I don't care enough to check.) In Java, x is private to C, all types in which C is nested, and all types nested in any of those types. It can also be accessed via reflection. In Javascript, x is public. In order to make a private-style variable, you need to use a local variable in the type's constructor. This prevents you from using method syntax in methods referring to that variable; you need to assign closures to fields instead. In Lua, x is public (or you use the Javascript workaround). In Perl, x is public. In Python, __x doesn't exist; it's syntactic sugar for _C__x. _C__x is public. In Ruby, x is protected (but can be accessed via reflection). In Rust, x is private to the module. In Swift, there are different versions of 'private' for private-to-type and private-to-source-file. So no, there is no one standard way of doing things that D violates. D uses a system that's tied for second place behind not having private variables at all.
Oct 28 2018
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Sunday, 28 October 2018 at 15:41:47 UTC, Neia Neutuladh wrote:

 In D, x is private to C and any types or functions defined in 
 the same module.
...and can be accessed via reflection (.tupleof). </Pedantry>
Oct 28 2018
next sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Sunday, 28 October 2018 at 15:47:15 UTC, Stanislav Blinov 
wrote:
 On Sunday, 28 October 2018 at 15:41:47 UTC, Neia Neutuladh 
 wrote:

 In D, x is private to C and any types or functions defined in 
 the same module.
...and can be accessed via reflection (.tupleof). </Pedantry>
Actually if you try to use it the compiler complains because D reflection is compile time.
Oct 28 2018
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Sunday, 28 October 2018 at 16:20:06 UTC, Jesse Phillips wrote:
 On Sunday, 28 October 2018 at 15:47:15 UTC, Stanislav Blinov 
 wrote:
 On Sunday, 28 October 2018 at 15:41:47 UTC, Neia Neutuladh 
 wrote:

 In D, x is private to C and any types or functions defined in 
 the same module.
...and can be accessed via reflection (.tupleof). </Pedantry>
Actually if you try to use it the compiler complains because D reflection is compile time.
Actually it doesn't complain ;)
Oct 28 2018
parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Sunday, 28 October 2018 at 16:26:33 UTC, Stanislav Blinov 
wrote:
 On Sunday, 28 October 2018 at 16:20:06 UTC, Jesse Phillips 
 wrote:
 On Sunday, 28 October 2018 at 15:47:15 UTC, Stanislav Blinov 
 wrote:
 On Sunday, 28 October 2018 at 15:41:47 UTC, Neia Neutuladh 
 wrote:

 In D, x is private to C and any types or functions defined 
 in the same module.
...and can be accessed via reflection (.tupleof). </Pedantry>
Actually if you try to use it the compiler complains because D reflection is compile time.
Actually it doesn't complain ;)
Oh, I was thinking of when using the field names to build out their access. Forgot about the direct access through the tuple.
Oct 29 2018
prev sibling next sibling parent Neia Neutuladh <neia ikeran.org> writes:
On Sun, 28 Oct 2018 15:47:15 +0000, Stanislav Blinov wrote:
 On Sunday, 28 October 2018 at 15:41:47 UTC, Neia Neutuladh wrote:
 
 In D, x is private to C and any types or functions defined in the same
 module.
...and can be accessed via reflection (.tupleof). </Pedantry>
Good point. I saw a bug report recently implying that this is unintended and subject to change, so maybe that won't remain true for long.
Oct 28 2018
prev sibling parent unprotected-entity <unprotected-entity gmail.com> writes:
On Sunday, 28 October 2018 at 15:47:15 UTC, Stanislav Blinov 
wrote:
 On Sunday, 28 October 2018 at 15:41:47 UTC, Neia Neutuladh 
 wrote:

 In D, x is private to C and any types or functions defined in 
 the same module.
...and can be accessed via reflection (.tupleof). </Pedantry>
Whenver that statement comes up, it needs to be mentioned, yet again, that access modifiers are not a 'security' feature. They "are a convenient design constraint, to help us structure our applications properly." - and yes, they are convenient within a module too (unless your module doesn't care about them - cause then they're completely useless). Using reflection to explicitly break open something, is not the same as leaving it completely open in the first place (within a module, where that is always the case).
Oct 31 2018