October 29, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | 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.
|
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bastiaan Veelo | 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);
};
-------
|
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | 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: >> >> Java, C++, and C# all treat `private` differently, so if you're 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. That your request to make D's `private` work like Java, C#, and C++ isn't 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. Do you want to make things work like C#? C# has a very strict notion of `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. |
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Neia Neutuladh | On Tuesday, 30 October 2018 at 01:33:50 UTC, Neia Neutuladh wrote: > > That your request to make D's `private` work like Java, C#, and 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). That is what I expected. This is what C++/c#/Java does. It's a 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 C++/Java/C# 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... |
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | 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.
|
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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.
};
------------------
|
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | 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?)
|
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | 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. |
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | 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: >> >> That your request to make D's `private` work like Java, C#, and C++ 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; } --- Java and C# do not have a way to declare friends. 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. C# doesn't let you do any of this. In C#, you can make something private 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). > > That is what I expected. This is what C++/c#/Java does. It's a reasonable expectation for someone looking at using D. Is it not? Again, C++, C#, and Java all do different things with protection attributes, so saying you want something that satisfies people's expectations when they're coming from C++, C#, or Java doesn't give an 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++, C#, and Java users to have an easier time with D's protection attributes 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. |
October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | 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.
|
Copyright © 1999-2021 by the D Language Foundation