www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Adding a new design constraint to D

reply forkit <forkit gmail.com> writes:
So there has been extensive discussions in other threads, around 
the idea of adding a new 'design constraint feature' to the D 
programming language.

The design constraint feature, is 'designed' to allow the 
programmer to make an explicit declaration, that some aspect of 
the design of a class, should be private to that class, and 
thereby make that aspect of the class (logically) inaccessible to 
code outside of that class, but in the same module.

The constraint could, in theory, apply to other types such as 
struct or enum. But the suggestion currently relates to the class 
type only.

The below example compiles just fine, as you would expect.

// ------
module test;
 safe:

class someClass
{
     private:
         string _id;

     public:
         void setID(string id)
         {
             // some condition(s), if met, then:
             _id = id;
         }
}

unittest
{
     someClass myclass = new someClass();
     myclass.setID("123");
}

// -----

Is the above code consistent with the design intent of someClass?

The answer must be yes, since in D, private is private to the 
module.

But what if the intent was to require other code to 'use the 
inteface' to access x?

The problem is, many coming to D, come from languages where you 
can already declare such an intent, and equally importantly, have 
that intent enforced by the compiler, at compile time.

But the D programming language has no feature to declare such an 
intent. So where does this leave those programmers?

The argument has been made, that D does not need such a feature, 
because scope is always at the module level.

But it does not follow, that scope at the module level eliminates 
the need for such a feature. That argument is not logical.

The next response, is that if you need this feature, then you can 
'simulate it' by putting the class that needs this feature, into 
its own module.

However, the one-class-per-module approach, imposes its own new 
design constraint, and not one the programmer necessarily makes 
of his/her own volition.

It also does not necessarily follow, that a class in its own 
module, is there for the purposes of stipulating this constraint.

There are any number of a reason, why a class might be put into 
its own module. You cannot infer anything from that. You'd have 
to speak the designer to know intent.

Other arguments have also been made against adding such a 
feature, but it is difficult to take them seriously - such as 
'why would a class ever need to hide something'.

Now the advantage of adding such a feature, is that it provides 
private at the scope level for those who want or expect such a 
feature, it provides evidence of the designers intent to separate 
implementations from interface, and the compiler which now knows 
the intent, can enforce that intent, at compile time.

So the only logical outcome of this discussion, is whether the 
benefit of adding a design constraint *option* to the language, 
outweighs the cost of adding it to the langauge.

The benefits of adding this feature appear to be self-evident.

So ultimately, this comes down to a benefit-vs-cost consideration.

The cost of adding it to the language, is less self-evident.

Is the cost, the unjustified cognitive burden of having both 
'private' and 'private(scope)', instead of just 'private'?

Is the cost - it's just too complicated to change the compiler 
source to accomodate this option?

What do you think the cost of adding such a feature is?
Jun 13 2022
next sibling parent reply JG <someone somewhere.com> writes:
On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
 So there has been extensive discussions in other threads, 
 around the idea of adding a new 'design constraint feature' to 
 the D programming language.

 The design constraint feature, is 'designed' to allow the 
 programmer to make an explicit declaration, that some aspect of 
 the design of a class, should be private to that class, and 
 thereby make that aspect of the class (logically) inaccessible 
 to code outside of that class, but in the same module.

 The constraint could, in theory, apply to other types such as 
 struct or enum. But the suggestion currently relates to the 
 class type only.

 The below example compiles just fine, as you would expect.

 // ------
 module test;
  safe:

 class someClass
 {
     private:
         string _id;

     public:
         void setID(string id)
         {
             // some condition(s), if met, then:
             _id = id;
         }
 }

 unittest
 {
     someClass myclass = new someClass();
     myclass.setID("123");
 }

 // -----

 Is the above code consistent with the design intent of 
 someClass?

 The answer must be yes, since in D, private is private to the 
 module.

 But what if the intent was to require other code to 'use the 
 inteface' to access x?

 The problem is, many coming to D, come from languages where you 
 can already declare such an intent, and equally importantly, 
 have that intent enforced by the compiler, at compile time.

 But the D programming language has no feature to declare such 
 an intent. So where does this leave those programmers?

 The argument has been made, that D does not need such a 
 feature, because scope is always at the module level.

 But it does not follow, that scope at the module level 
 eliminates the need for such a feature. That argument is not 
 logical.

 The next response, is that if you need this feature, then you 
 can 'simulate it' by putting the class that needs this feature, 
 into its own module.

 However, the one-class-per-module approach, imposes its own new 
 design constraint, and not one the programmer necessarily makes 
 of his/her own volition.

 It also does not necessarily follow, that a class in its own 
 module, is there for the purposes of stipulating this 
 constraint.

 There are any number of a reason, why a class might be put into 
 its own module. You cannot infer anything from that. You'd have 
 to speak the designer to know intent.

 Other arguments have also been made against adding such a 
 feature, but it is difficult to take them seriously - such as 
 'why would a class ever need to hide something'.

 Now the advantage of adding such a feature, is that it provides 
 private at the scope level for those who want or expect such a 
 feature, it provides evidence of the designers intent to 
 separate implementations from interface, and the compiler which 
 now knows the intent, can enforce that intent, at compile time.

 So the only logical outcome of this discussion, is whether the 
 benefit of adding a design constraint *option* to the language, 
 outweighs the cost of adding it to the langauge.

 The benefits of adding this feature appear to be self-evident.

 So ultimately, this comes down to a benefit-vs-cost 
 consideration.

 The cost of adding it to the language, is less self-evident.

 Is the cost, the unjustified cognitive burden of having both 
 'private' and 'private(scope)', instead of just 'private'?

 Is the cost - it's just too complicated to change the compiler 
 source to accomodate this option?

 What do you think the cost of adding such a feature is?
I think you are missing part of your analysis. Is this a complete feature you are suggesting to be added? I also haven't thought it through to the end but for instance wouldn't something like "friend" need to be added shortly after adding this? Another point that you are perhaps missing is that each person who uses D probably has at least one thing they would like added to the language (which they consider to be extremely important). If all these things were added, D would be much more complicated than it is now, even if each is a minor change. In reading what you wrote I didn't find the following clear:
 However, the one-class-per-module approach, imposes its own new 
 design constraint, and not one the programmer necessarily makes 
 of his/her own volition.
 It also does not necessarily follow, that a class in its own 
 module, is there for the purposes of stipulating this 
 constraint.
Jun 13 2022
parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 06:09:57 UTC, JG wrote:
 I think you are missing part of your analysis. Is this a 
 complete feature you are suggesting to be added? I also haven't 
 thought it through to the end but for instance wouldn't 
 something like "friend" need to be added shortly after adding 
 this?
No. I cannot see how such a concept (of needing to add friend) would ever apply here??
 Another point that you are perhaps missing is that each person 
 who uses D probably has at least one thing they would like 
 added to the language (which they consider to be extremely 
 important). If all these things were added, D would be much 
 more complicated than it is now, even if each is a minor change.
This may be a valid reason for not adding 'any' new feature, but it is not a valid reason for not adding 'this' feature.
 In reading what you wrote I didn't find the following clear:

 However, the one-class-per-module approach, imposes its own 
 new design constraint, and not one the programmer necessarily 
 makes of his/her own volition.
 It also does not necessarily follow, that a class in its own 
 module, is there for the purposes of stipulating this 
 constraint.
Putting one class in a module by itself, means no other code except that class is in that module, and therefore the class does not need to 'hide' anything from any other code in the module - cause there isn't any other code in the module. But putting one class in a module by itself, demonstrates no intent whatsoever. You have to ask the designer why they chose to do that. The option suggested would 'explicately' specify an intent, and can do so *without* enforcing a one-class-per-module design constraint onto the programmer.
Jun 13 2022
parent reply JG <someone somewhere.com> writes:
On Tuesday, 14 June 2022 at 06:43:36 UTC, forkit wrote:
 On Tuesday, 14 June 2022 at 06:09:57 UTC, JG wrote:
 I think you are missing part of your analysis. Is this a 
 complete feature you are suggesting to be added? I also 
 haven't thought it through to the end but for instance 
 wouldn't something like "friend" need to be added shortly 
 after adding this?
No. I cannot see how such a concept (of needing to add friend) would ever apply here??
So there is no use case for "friend class" in C++?
 Another point that you are perhaps missing is that each person 
 who uses D probably has at least one thing they would like 
 added to the language (which they consider to be extremely 
 important). If all these things were added, D would be much 
 more complicated than it is now, even if each is a minor 
 change.
This may be a valid reason for not adding 'any' new feature, but it is not a valid reason for not adding 'this' feature.
Isn't that a bit of a weak answer? Couldn't anybody proposing a feature they want answer the same way?
 In reading what you wrote I didn't find the following clear:

 However, the one-class-per-module approach, imposes its own 
 new design constraint, and not one the programmer necessarily 
 makes of his/her own volition.
 It also does not necessarily follow, that a class in its own 
 module, is there for the purposes of stipulating this 
 constraint.
Putting one class in a module by itself, means no other code except that class is in that module, and therefore the class does not need to 'hide' anything from any other code in the module - cause there isn't any other code in the module. But putting one class in a module by itself, demonstrates no intent whatsoever. You have to ask the designer why they chose to do that. The option suggested would 'explicately' specify an intent, and can do so *without* enforcing a one-class-per-module design constraint onto the programmer.
If what you say were true, couldn't we say that from now on putting a class alone in a module shows the intent of making private mean private to the class?
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 07:05:14 UTC, JG wrote:
 On Tuesday, 14 June 2022 at 06:43:36 UTC, forkit wrote:
 On Tuesday, 14 June 2022 at 06:09:57 UTC, JG wrote:
 I think you are missing part of your analysis. Is this a 
 complete feature you are suggesting to be added? I also 
 haven't thought it through to the end but for instance 
 wouldn't something like "friend" need to be added shortly 
 after adding this?
No. I cannot see how such a concept (of needing to add friend) would ever apply here??
So there is no use case for "friend class" in C++?
My point is, there is no problem making friends in D, cause everyone is already your friend - you got no choice anyway - that's how it is, full stop. the problem is in the unfriending part. if you take this too the extreme, as some no doubt will, the argument will be 'well if they're not friends then why put them in the same module?'. but that's a strawman argument - which results from taking the point to the extreme. I'm about friends that can have the capacity to keep some part of their existence to themselves, and under their control. this is what D lacks. friends are defined by their ability to mutate every aspect of each other. However, in D they are (cause it lacks this feature I'm suggesting).
 Another point that you are perhaps missing is that each 
 person who uses D probably has at least one thing they would 
 like added to the language (which they consider to be 
 extremely important). If all these things were added, D would 
 be much more complicated than it is now, even if each is a 
 minor change.
This may be a valid reason for not adding 'any' new feature, but it is not a valid reason for not adding 'this' feature.
Isn't that a bit of a weak answer? Couldn't anybody proposing a feature they want answer the same way?
To understand the downside of implementing this particular feature, I need to know arguments specific to this feature. Arguments that can be applied to any feature are not relevant, in this context, that is what I'm saying here. The argument put forward relates to 'change' in general. Not this feature, specifically.
 In reading what you wrote I didn't find the following clear:

 However, the one-class-per-module approach, imposes its own 
 new design constraint, and not one the programmer 
 necessarily makes of his/her own volition.
 It also does not necessarily follow, that a class in its own 
 module, is there for the purposes of stipulating this 
 constraint.
Putting one class in a module by itself, means no other code except that class is in that module, and therefore the class does not need to 'hide' anything from any other code in the module - cause there isn't any other code in the module. But putting one class in a module by itself, demonstrates no intent whatsoever. You have to ask the designer why they chose to do that. The option suggested would 'explicately' specify an intent, and can do so *without* enforcing a one-class-per-module design constraint onto the programmer.
If what you say were true, couldn't we say that from now on putting a class alone in a module shows the intent of making private mean private to the class?
any convention can be used to indicate intent. I don't wont to indicate intent. I want to explicately state intent. I want the compiler to enforce that intent. I want anyone reading my code, to immediately understand my intent, and not rely on them understanding my 'conventions'.
Jun 14 2022
parent forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 01:51:41 UTC, forkit wrote:
 ...
 friends are defined by their ability to mutate every aspect of 
 each other.

 However, in D they are (cause it lacks this feature I'm 
 suggesting).
ooops. of course: "friends are defined by their ability to mutate every aspect of each other." should have been: "friends **aren't** defined by their ability to mutate every aspect of each other."
Jun 14 2022
prev sibling next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
 [...]
 So the only logical outcome of this discussion, is whether the 
 benefit of adding a design constraint *option* to the language, 
 outweighs the cost of adding it to the langauge.

 The benefits of adding this feature appear to be self-evident.

 So ultimately, this comes down to a benefit-vs-cost 
 consideration.

 The cost of adding it to the language, is less self-evident.

 Is the cost, the unjustified cognitive burden of having both 
 'private' and 'private(scope)', instead of just 'private'?

 Is the cost - it's just too complicated to change the compiler 
 source to accomodate this option?

 What do you think the cost of adding such a feature is?
If the object in the same module is visible, why make it private when you're already writing code? You are already partially isolating using underscore (Foo._id). For example, Foo.length will never conflict. What difference would it make to see or not see this error?
 Error: no property `id` for type `source.Foo`
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 07:12:18 UTC, Salih Dincer wrote:
 If the object in the same module is visible, why make it 
 private when you're already writing code? You are already 
 partially isolating using underscore (Foo._id). For example, 
 Foo.length will never conflict.

 What difference would it make to see or not see this error?

 Error: no property `id` for type `source.Foo`
yes, 'private' in this case is pointless. but the example, is the kind of code I, and many like me, will come to D and write, expecting that private means private to the scope of the class. Since private means private to the scope of the module, how then do I (and those like me) specifiy that intent in D? That's the question that has prompted this idea of adding a scope private option. Also, while some use the underscore convention to indicate something is scope private, it doesn't necessarily follow that anyone who used underscore was specifying that to be scope private. So isolating using an underscore doesn't really indicate intent, unless that was the intent, and it also depends on other considerations (e.g you teams coding style, etc). I'm talking about an option that explicitely, unmistakingly, shows intent, and furthermore, an intent the compiler recognises and enforces at compile time. private(scope) <- the intent cannot my inferred here, it is explicit. _var <- does that underscore infer an intent for scope private?? You need additional information to make that judgement. An underscore 'convention' is no substitute to an explicit intent that cannot be missinterpreted or mistakingly bypassed - the compiler will know my intent, and enforce it, and anyone reading/modifying/using my code will know my intent also. the same conclusion must also apply to the one-class-per-module argument. it's about knowing the intent, vs guessing what the intent was (or needing to obtain more information to understand the intent - e.g is it because our coding style say use an underscore to indicate this is scope private). the compiler cannot infer why you used an underscore, nor can it infer why you put a class in a file by itself.
Jun 14 2022
next sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Tuesday, 14 June 2022 at 07:34:43 UTC, forkit wrote:
 [...]
 _var <- does that underscore infer an intent for scope 
 private?? You need additional information to make that 
 judgement.

 An underscore 'convention' is no substitute to an explicit 
 intent that cannot be missinterpreted or mistakingly bypassed - 
 the compiler will know my intent, and enforce it, and anyone 
 reading/modifying/using my code will know my intent also.

 the same conclusion must also apply to the one-class-per-module 
 argument.
 [...]
You're right... SDB 79
Jun 14 2022
prev sibling parent reply The Zealot <zod zod.zod> writes:
"but the example, is the kind of code I, and many like me, will 
come to D and write, expecting that private means private to the 
scope of the class."
That is a _you_ problem though. D ist different to other 
languages, you cannot except it to have all the features, or for 
features to behave the same way as other languages.

Now you can solve the 'problem' of not having _class private_ two 
ways already.
a) put the class in it's own module.
b) put the class decleration inside a function and use an 
interface declared at module scope.

In addition, _class private_ doesn't even solve the encapsulation 
'problem' in the first place.
All member functions could still access all private class 
members. Consider the following:
```
class Foo {
class_private int _a;
void setA(int v) { _a = v < 42 ? v : 42; }
void oh_no() { _a = 666; /*fail!!*/ }
}
```

IMHO, _class private_ doesn't add any _value_ whatsoever, and it 
complicates metaprogramming.
Jun 14 2022
parent reply bauss <jj_1337 live.dk> writes:
On Tuesday, 14 June 2022 at 10:21:34 UTC, The Zealot wrote:
 a) put the class in it's own module.
No you really can't and I already proved that with a couple examples in the other discussions on this topic; there are situations where you cannot do that, such as accessing private fields on a parent class using a sub class type within the parent class' module. That's why the module-level private is a lie in D or at least incomplete.
Jun 14 2022
next sibling parent reply The Zealot <zod zod.zod> writes:
On Tuesday, 14 June 2022 at 10:50:56 UTC, bauss wrote:
 On Tuesday, 14 June 2022 at 10:21:34 UTC, The Zealot wrote:
 a) put the class in it's own module.
No you really can't and I already proved that with a couple examples in the other discussions on this topic; there are situations where you cannot do that, such as accessing private fields on a parent class using a sub class type within the parent class' module. That's why the module-level private is a lie in D or at least incomplete.
The code you posted works exactly as it should. your function void handle(Bar child) does access the class Bar of another module, and the members of foo are not accessible. and you can implement the desired behaviour like this: import b; void handle(Bar child) if(isDerivedFrom!(Foo, Bar)) { (cast(Foo)child)._c += child.c; }
Jun 14 2022
parent reply bauss <jj_1337 live.dk> writes:
On Tuesday, 14 June 2022 at 11:04:55 UTC, The Zealot wrote:
 On Tuesday, 14 June 2022 at 10:50:56 UTC, bauss wrote:
 On Tuesday, 14 June 2022 at 10:21:34 UTC, The Zealot wrote:
 a) put the class in it's own module.
No you really can't and I already proved that with a couple examples in the other discussions on this topic; there are situations where you cannot do that, such as accessing private fields on a parent class using a sub class type within the parent class' module. That's why the module-level private is a lie in D or at least incomplete.
The code you posted works exactly as it should. your function void handle(Bar child) does access the class Bar of another module, and the members of foo are not accessible. and you can implement the desired behaviour like this: import b; void handle(Bar child) if(isDerivedFrom!(Foo, Bar)) { (cast(Foo)child)._c += child.c; }
No it does not. You should never have to cast to a parent type, NEVER! That is a red flag if you have to do that, a major one at that.
Jun 14 2022
parent reply The Zealot <zod zod.zod> writes:
On Tuesday, 14 June 2022 at 12:09:57 UTC, bauss wrote:
 On Tuesday, 14 June 2022 at 11:04:55 UTC, The Zealot wrote:
 On Tuesday, 14 June 2022 at 10:50:56 UTC, bauss wrote:
 On Tuesday, 14 June 2022 at 10:21:34 UTC, The Zealot wrote:
 a) put the class in it's own module.
No you really can't and I already proved that with a couple examples in the other discussions on this topic; there are situations where you cannot do that, such as accessing private fields on a parent class using a sub class type within the parent class' module. That's why the module-level private is a lie in D or at least incomplete.
The code you posted works exactly as it should. your function void handle(Bar child) does access the class Bar of another module, and the members of foo are not accessible. and you can implement the desired behaviour like this: import b; void handle(Bar child) if(isDerivedFrom!(Foo, Bar)) { (cast(Foo)child)._c += child.c; }
No it does not. You should never have to cast to a parent type, NEVER! That is a red flag if you have to do that, a major one at that.
no this is actually perfectly fine, as the code ensures at compiletime that Bar is in fact a subtype of Foo, so the cast is always valid. You have to be explicit that you actually want to use Foo's _c; or else adding a _c variable to Bar silently changes the behaviour of your code. This works as intended.
Jun 14 2022
parent The Zealot <zod zod.zod> writes:
 import b;
 void handle(Bar child) if(isDerivedFrom!(Foo, Bar))
 {
   (cast(Foo)child)._c += child.c;
 }
No it does not. You should never have to cast to a parent type, NEVER! That is a red flag if you have to do that, a major one at that.
no this is actually perfectly fine, as the code ensures at compiletime that Bar is in fact a subtype of Foo, so the cast is always valid. You have to be explicit that you actually want to use Foo's _c; or else adding a _c variable to Bar silently changes the behaviour of your code. This works as intended.
and just to be clear, you don't even need to do it with an explicit cast. All you have to do is access _c through a baseclass pointer.
Jun 14 2022
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 14 June 2022 at 10:50:56 UTC, bauss wrote:

 No you really can't and I already proved that with a couple 
 examples in the other discussions on this topic; there are 
 situations where you cannot do that, such as accessing private 
 fields on a parent class using a sub class type within the 
 parent class' module.
And Paul did show you how to do that with `child.Foo._c`.
Jun 14 2022
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 June 2022 at 12:19:40 UTC, Mike Parker wrote:
 On Tuesday, 14 June 2022 at 10:50:56 UTC, bauss wrote:

 No you really can't and I already proved that with a couple 
 examples in the other discussions on this topic; there are 
 situations where you cannot do that, such as accessing private 
 fields on a parent class using a sub class type within the 
 parent class' module.
And Paul did show you how to do that with `child.Foo._c`.
Which is a pointless thing to say, you are still violating the subtyping relationship.
Jun 14 2022
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 14 June 2022 at 12:28:24 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 14 June 2022 at 12:19:40 UTC, Mike Parker wrote:\
 And Paul did show you how to do that with `child.Foo._c`.
Which is a pointless thing to say, you are still violating the subtyping relationship.
So then what do you do when your direct access to `child._c` suddenly starts causing a subtle bug because someone added later added a `_c` member to the public interface of `Bar`? Private members are not inherited and do not impact the public interface.
Jun 14 2022
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 June 2022 at 12:33:53 UTC, Mike Parker wrote:
 On Tuesday, 14 June 2022 at 12:28:24 UTC, Ola Fosheim Grøstad 
 wrote:
 On Tuesday, 14 June 2022 at 12:19:40 UTC, Mike Parker wrote:\
 And Paul did show you how to do that with `child.Foo._c`.
Which is a pointless thing to say, you are still violating the subtyping relationship.
So then what do you do when your direct access to `child._c` suddenly starts causing a subtle bug because someone added later added a `_c` member to the public interface of `Bar`? Private members are not inherited and do not impact the public interface.
You get an error, just like in C++! Then you disambiguate. (Private members are inherited 100%.)
Jun 14 2022
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 June 2022 at 12:39:26 UTC, Ola Fosheim Grøstad 
wrote:
 You get an error, just like in C++!
Actually I was wrong, you don't get an error in C++. You get the subclass member.
Jun 14 2022
prev sibling parent reply bauss <jj_1337 live.dk> writes:
On Tuesday, 14 June 2022 at 12:33:53 UTC, Mike Parker wrote:
 So then what do you do when your direct access to `child._c` 
 suddenly starts causing a subtle bug because someone added 
 later added a `_c` member to the public interface of `Bar`? 
 Private members are not inherited and do not impact the public 
 interface.
That shouldn't matter, if you have access to screw up with _c, then you have access to the module and thus it is your own responsibility to make sure you don't create subtle bugs. Isn't that the whole point behind module-level privacy? You have access to the module, thus you have control over the module. It shouldn't matter how you get into the module etc. since you're the owner of the module, then you're the one responsible for it. You see, your argument against all of this is the exact argument that is for type-level privacy, since you wouldn't be able to create a subtle bug like this and you wouldn't be able to cast to the parent type in the module and hack your way around that way either. It solves both problems.
Jun 14 2022
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 14 June 2022 at 12:39:33 UTC, bauss wrote:

 That shouldn't matter, if you have access to screw up with _c, 
 then you have access to the module and thus it is your own 
 responsibility to make sure you don't create subtle bugs.

 Isn't that the whole point behind module-level privacy?

 You have access to the module, thus you have control over the 
 module. It shouldn't matter how you get into the module etc. 
 since you're the owner of the module, then you're the one 
 responsible for it.

 You see, your argument against all of this is the exact 
 argument that is for type-level privacy, since you wouldn't be 
 able to create a subtle bug like this and you wouldn't be able 
 to cast to the parent type in the module and hack your way 
 around that way either.

 It solves both problems.
No, that doesn't hold in your example because Bar was *not* in the same module. Going through .Foo gives you access to Foo's private parts because it *is* in the same module. If you want to argue that you should be able to access child._c when both Bar and Foo are in the same module, well, you can: ```d class Foo { private int _c; } class Bar : Foo { } void baz(Bar child) { child._c = 10; } void main() { Bar b = new Bar; baz(b); writeln(b._c); } ```
Jun 14 2022
parent reply bauss <jj_1337 live.dk> writes:
On Tuesday, 14 June 2022 at 12:47:31 UTC, Mike Parker wrote:
 On Tuesday, 14 June 2022 at 12:39:33 UTC, bauss wrote:

 That shouldn't matter, if you have access to screw up with _c, 
 then you have access to the module and thus it is your own 
 responsibility to make sure you don't create subtle bugs.

 Isn't that the whole point behind module-level privacy?

 You have access to the module, thus you have control over the 
 module. It shouldn't matter how you get into the module etc. 
 since you're the owner of the module, then you're the one 
 responsible for it.

 You see, your argument against all of this is the exact 
 argument that is for type-level privacy, since you wouldn't be 
 able to create a subtle bug like this and you wouldn't be able 
 to cast to the parent type in the module and hack your way 
 around that way either.

 It solves both problems.
No, that doesn't hold in your example because Bar was *not* in the same module. Going through .Foo gives you access to Foo's private parts because it *is* in the same module. If you want to argue that you should be able to access child._c when both Bar and Foo are in the same module, well, you can: ```d class Foo { private int _c; } class Bar : Foo { } void baz(Bar child) { child._c = 10; } void main() { Bar b = new Bar; baz(b); writeln(b._c); } ```
Sure Bar wasn't in the same module, but Foo is and Bar inherits from Foo, thus Bar is Foo and Foo has access to _c in Foo's module and thus Bar should have access to Foo's private members in Foo's module, because Bar is Foo. It's really not that difficult to grasp such a concept. Here it is illustrated with my terrible graphic skills: https://i.postimg.cc/0Q3XSN47/illustrated.png
Jun 14 2022
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 14 June 2022 at 12:57:57 UTC, bauss wrote:

 Sure Bar wasn't in the same module, but Foo is and Bar inherits 
 from Foo, thus Bar is Foo and Foo has access to _c in Foo's 
 module and thus Bar should have access to Foo's private members 
 in Foo's module, because Bar is Foo.

 It's really not that difficult to grasp such a concept.
Will you please stop insulting my intelligence? I understand what you are saying. I'm just asserting that it's wrong. Bar has the *public* interface of Foo, true, but it does not have the private one. The private one is internal to Foo, so to get at it through an instance of Bar, then Bar either has to be in the same module as Foo, or you have to convert the instance to a Foo first. This is core to D's implementation of classes. If you access the private members of a superclass through instances of its subclass in the way that your original example did, then you are opening yourself up to a potential future bug. So the compiler prevents you from doing it and requires you to explicitly do it through the instance.SuperClass.field syntax. If that behavior were to change so that `instance.field` works in your example, then we'd be weakening the implementation, not strengthening it.
Jun 14 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 June 2022 at 13:06:02 UTC, Mike Parker wrote:
 Bar has the *public* interface of Foo, true, but it does not 
 have the private one. The private one is internal to Foo, so to 
 get at it through an instance of Bar, then Bar either has to be 
 in the same module as Foo, or you have to convert the instance 
 to a Foo first.
This isn't exactly the end of the universe, but I don't see how shadowing public members is better than shadowing private members. You end up with the same issues. If D was principled about this, should it not prevent shadowing of public members? As it is, "private" in D is more than an access restriction, you also change the lookup rules. (Clearly not the end of the world, as you would typically not write such code.)
Jun 14 2022
next sibling parent The Zealot <zod zod.zod> writes:
On Tuesday, 14 June 2022 at 13:35:13 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 14 June 2022 at 13:06:02 UTC, Mike Parker wrote:
 this, should it not prevent shadowing of public members?
I'd say it should, and i'd call this a bug. it should either require an override specifier, or the call side to be explicit
Jun 14 2022
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 14 June 2022 at 13:35:13 UTC, Ola Fosheim Grøstad 
wrote:

 You end up with the same issues. If D was principled about 
 this, should it not prevent shadowing of public members?
Yes, it should, actually.
Jun 14 2022
prev sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Tuesday, 14 June 2022 at 12:57:57 UTC, bauss wrote:

 Sure Bar wasn't in the same module, but Foo is and Bar inherits 
 from Foo, thus Bar is Foo and Foo has access to _c in Foo's 
 module and thus Bar should have access to Foo's private members 
 in Foo's module, because Bar is Foo.
Despite the fact you can access Foo._c, you can't access it through a different path. This is how D's scopes work, and it makes sense. Consider: ```d module a; import b; int x; void foo() { b.x = 1; // no access to x through b.x, even though the variable is visible in a. } ``` ```d module b; import a; private alias x = a.x; ``` File systems work in the same way - you can't access a node via a path going through inaccessible nodes even if the target node is accessible from the current node via other paths. That is, the module-level 'private' is still bad design, but it works consistently.
Jun 14 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 June 2022 at 13:35:21 UTC, Max Samukha wrote:
 On Tuesday, 14 June 2022 at 12:57:57 UTC, bauss wrote:

 Sure Bar wasn't in the same module, but Foo is and Bar 
 inherits from Foo, thus Bar is Foo and Foo has access to _c in 
 Foo's module and thus Bar should have access to Foo's private 
 members in Foo's module, because Bar is Foo.
Despite the fact you can access Foo._c, you can't access it through a different path.
It isn't necessarily through a different path unless you think that Bar is cloaking Foo, basically redoing everything that is Foo. So it is a matter of philosophy: do you think that Bar is an extension of Foo? Or do you think that Bar is a shell around Foo? From a purist OO viewpoint then Bar should be only an addition to Foo with no ability to redefine anything Foo'ish without Foo's consent. (C++ does not belong in this category I think…) I believe it is a mistake to mix up lookup with access, because it means you cannot give or grant access without having to rewrite code elsewhere. It also makes it more difficult to refactor (move a class from one context to another). Not really the most pressing issue for D though.
Jun 14 2022
parent reply Max Samukha <maxsamukha gmail.com> writes:
On Tuesday, 14 June 2022 at 13:49:30 UTC, Ola Fosheim Grøstad 
wrote:

 It isn't necessarily through a different path unless you think 
 that Bar is cloaking Foo, basically redoing everything that is 
 Foo.
D encourages me to think about it as being similar to 'alias this', which seems to behave differently: ```d module a; import b; struct Foo { private int _c; } void foo(Bar b) { b._c = 1; // passes, to Mike's and my surprise } void main() { } ``` ```d module b; import a; struct Bar { Foo foo; alias foo this; } ```
Jun 14 2022
next sibling parent The Zealot <zod zod.zod> writes:
On Tuesday, 14 June 2022 at 16:33:10 UTC, Max Samukha wrote:
 On Tuesday, 14 June 2022 at 13:49:30 UTC, Ola Fosheim Grøstad 
 wrote:

 It isn't necessarily through a different path unless you think 
 that Bar is cloaking Foo, basically redoing everything that is 
 Foo.
D encourages me to think about it as being similar to 'alias this', which seems to behave differently: ```d module a; import b; struct Foo { private int _c; } void foo(Bar b) { b._c = 1; // passes, to Mike's and my surprise } void main() { } ``` ```d module b; import a; struct Bar { Foo foo; alias foo this; } ```
that looks like a bug too
Jun 14 2022
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 14 June 2022 at 16:33:10 UTC, Max Samukha wrote:
 On Tuesday, 14 June 2022 at 13:49:30 UTC, Ola Fosheim Grøstad 
 wrote:

 It isn't necessarily through a different path unless you think 
 that Bar is cloaking Foo, basically redoing everything that is 
 Foo.
D encourages me to think about it as being similar to 'alias this', which seems to behave differently:
`alias this` is a weird special case. It doesn't really behave like anything else in the language. You probably shouldn't draw any broad conclusions based on the behavior of `alias this`.
Jun 14 2022
parent Max Samukha <maxsamukha gmail.com> writes:
On Tuesday, 14 June 2022 at 16:57:34 UTC, Paul Backus wrote:

 `alias this` is a weird special case. It doesn't really behave 
 like anything else in the language. You probably shouldn't draw 
 any broad conclusions based on the behavior of `alias this`.
In this simple case scoping rules should be exactly the same as those for class inheritance. Otherwise, we failed (or D is fundamentally incompatible with the way I think).
Jun 14 2022
prev sibling next sibling parent reply bauss <jj_1337 live.dk> writes:
On Tuesday, 14 June 2022 at 12:19:40 UTC, Mike Parker wrote:
 On Tuesday, 14 June 2022 at 10:50:56 UTC, bauss wrote:

 No you really can't and I already proved that with a couple 
 examples in the other discussions on this topic; there are 
 situations where you cannot do that, such as accessing private 
 fields on a parent class using a sub class type within the 
 parent class' module.
And Paul did show you how to do that with `child.Foo._c`.
Not in a legal way.
Jun 14 2022
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 14 June 2022 at 12:35:24 UTC, bauss wrote:
 On Tuesday, 14 June 2022 at 12:19:40 UTC, Mike Parker wrote:
 And Paul did show you how to do that with `child.Foo._c`.
Not in a legal way.
What do you mean?
Jun 14 2022
prev sibling parent Tejas <notrealemail gmail.com> writes:
On Tuesday, 14 June 2022 at 12:35:24 UTC, bauss wrote:
 On Tuesday, 14 June 2022 at 12:19:40 UTC, Mike Parker wrote:
 On Tuesday, 14 June 2022 at 10:50:56 UTC, bauss wrote:

 No you really can't and I already proved that with a couple 
 examples in the other discussions on this topic; there are 
 situations where you cannot do that, such as accessing 
 private fields on a parent class using a sub class type 
 within the parent class' module.
And Paul did show you how to do that with `child.Foo._c`.
Not in a legal way.
It is literally part of the [language spec](https://dlang.org/spec/class.html#fields), how is it illegal?????
 Members of a base class can be accessed by prepending the name 
 of the base class  followed by a dot:
```d class A { int a; int a2;} class B : A { int a; } void foo(B b) { b.a = 3; // accesses field B.a b.a2 = 4; // accesses field A.a2 b.A.a = 5; // accesses field A.a } ```
Jun 14 2022
prev sibling parent ryuukk_ <ryuukk.devv gmail.com> writes:
I don't think that's needed at all..

I'd rather see improvements to the core language

- tagged union
- .Enum value
- tuples for multiple values return
- built in language server


It's like shortened methods, =>, if you need that, why even use a 



private private, is some C++ shenanigans, the idea of "private 
private" already sounds.. wrong..

just reuse package and problem solved

     package:
     private int myPriv;

focus focus!
Jun 15 2022
prev sibling next sibling parent reply claptrap <clap trap.com> writes:
On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
 But the D programming language has no feature to declare such 
 an intent. So where does this leave those programmers?
It leaves 99.9% of them going "Oh OK" and carrying on programming.
 The argument has been made, that D does not need such a 
 feature, because scope is always at the module level.
The argument is this... "If you have access to the source code of the module then you can already muck about with the internals of the class, you ought to know what you're doing so adding "strict private" doesn't actually gain you anything.
 But it does not follow, that scope at the module level 
 eliminates the need for such a feature. That argument is not 
 logical.
It eliminates 99% of the need for it. The other 1% is a gift to the gods of compromise in exchange for friend access between classes that need it.
 Now the advantage of adding such a feature, is that it provides 
 private at the scope level for those who want or expect such a 
 feature, it provides evidence of the designers intent to 
 separate implementations from interface, and the compiler which 
 now knows the intent, can enforce that intent, at compile time.
If "People coming from Java expect X" was a good argument for adding X then D would just be Java.
 So the only logical outcome of this discussion, is whether the 
 benefit of adding a design constraint *option* to the language, 
 outweighs the cost of adding it to the langauge.
The onus is on you to demonstrate a genuine need for it other than it's just what people expect.
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 10:07:49 UTC, claptrap wrote:
 It leaves 99.9% of them going "Oh OK" and carrying on 
 programming.
well.. it didn't take long for the passive-aggresive types to come out of the woodwork...now did it. my argument clearly lays out why I believe it is useful. your argument is, 'it's not important to us - because you (me) are just the 0.1% , and we're the 99.9%'. I don't find that a credible argument worth considering any further.
 The argument is this... "If you have access to the source code 
 of the module then you can already muck about with the 
 internals of the class, you ought to know what you're doing so 
 adding "strict private" doesn't actually gain you anything.
 
 ...
the argument that I have access to the source file is a strawman, and will not be considered any further.
 It eliminates 99% of the need for it. The other 1% is a gift to 
 the gods of compromise in exchange for friend access between 
 classes that need it.
The decision to friend or unfriend should be a design consideration, and not a design constraint enforced onto you by the language. D has removed the need to use C++ like friend. Now I need a suitable, enforcable, design constraint, so i can unfriend.
 If "People coming from Java expect X" was a good argument for 
 adding X then D would just be Java.
I don't know why Java always comes up?? most widely used programming langauges in the world. The concept already exists across these languages. Millions of programmer already work with this concept (although apprarently it's not as clear cut in Java as one would expect). What you're saying is, either these millions of programmers don't really need this feature, or they just don't need it in D. I cannot find the basis for either assertion in your response.
 The onus is on you to demonstrate a genuine need for it other 
 than it's just what people expect.
I'm pretty sure that's exactly what I've done.
Jun 14 2022
parent reply Dom Disc <dominikus scherkl.de> writes:
On Tuesday, 14 June 2022 at 10:47:18 UTC, forkit wrote:
 The decision to friend or unfriend should be a design 
 consideration, and not a design constraint enforced onto you by 
 the language.

 D has removed the need to use C++ like friend.
Yes, but it reached this by making the module the encapsulation unit. If you want something to be a friend, put it in the same file. If you want it to be no friend, put it in a different file. If it's a member, you can do nothing about it - not with module level nor with class level privacy. Also not in C++ or Java or any other language I know about.
 Now I need a suitable, enforcable, design constraint, so i can 
 unfriend.
Yes, now we're talking. What we need is no new level of privacy, we need a method to unfriend something - especially applicable also to member functions. THIS would give us some real new benefit. This could be realized by a new UDA (adding to the attribute soup): noPrivateAccess or likewise. Add this to a function and the compiler will error out if you try to use any module private variable within this function. The problem is: This may not be useful very often, because there may be a lot of private things, and you would like only some of them to be not accessible by this function. So you can add a list of variables that should not be usable: noPrivateAccess(bla, blubb) Now this becomes really ugly. Maybe vice versa would be better: give it a list of private stuff it is allowed to access: limitPrivateAccess(x) I would think this is the best solution, because most of the time a single function will need only access to very few private variables. Of course without annotation a function can access everything within the module as always, to not breaking any existing code.
Jun 14 2022
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 June 2022 at 17:16:04 UTC, Dom Disc wrote:
 If it's a member, you can do nothing about it - not with module 
 level nor with class level privacy. Also not in C++ or Java or 
 any other language I know about.
Not sure what you meant by this. You can make the member a class that has its own privacy with a selective set of friends.
Jun 14 2022
parent reply Dom Disc <dominikus scherkl.de> writes:
On Tuesday, 14 June 2022 at 17:24:31 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 14 June 2022 at 17:16:04 UTC, Dom Disc wrote:
 If it's a member, you can do nothing about it - not with 
 module level nor with class level privacy. Also not in C++ or 
 Java or any other language I know about.
Not sure what you meant by this. You can make the member a class that has its own privacy with a selective set of friends.
What I mean is: You cannot prevent a member function from having access to the private variables of the class. Even if it should not touch them.
Jun 14 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 June 2022 at 20:04:14 UTC, Dom Disc wrote:
 On Tuesday, 14 June 2022 at 17:24:31 UTC, Ola Fosheim Grøstad 
 wrote:
 On Tuesday, 14 June 2022 at 17:16:04 UTC, Dom Disc wrote:
 If it's a member, you can do nothing about it - not with 
 module level nor with class level privacy. Also not in C++ or 
 Java or any other language I know about.
Not sure what you meant by this. You can make the member a class that has its own privacy with a selective set of friends.
What I mean is: You cannot prevent a member function from having access to the private variables of the class. Even if it should not touch them.
This seems to compile: ```C++ class A { public: inline void f(); inline void g(); private: class X { int value; friend void A::f(); }; X x{}; }; void A::f(){ x.value++; } void A::g(){ //illegal: x.value++; } ```
Jun 14 2022
parent reply Dom Disc <dominikus scherkl.de> writes:
On Tuesday, 14 June 2022 at 20:41:35 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 14 June 2022 at 20:04:14 UTC, Dom Disc wrote:
 On Tuesday, 14 June 2022 at 17:24:31 UTC, Ola Fosheim Grøstad 
 wrote:
 On Tuesday, 14 June 2022 at 17:16:04 UTC, Dom Disc wrote:
 If it's a member, you can do nothing about it - not with 
 module level nor with class level privacy. Also not in C++ 
 or Java or any other language I know about.
Not sure what you meant by this. You can make the member a class that has its own privacy with a selective set of friends.
What I mean is: You cannot prevent a member function from having access to the private variables of the class. Even if it should not touch them.
This seems to compile:
Ok, you got me. Didn't thought about friends of sub-classes. But in D I don't know ... maybe something similar is possible?
Jun 14 2022
parent reply Zoadian <no no.no> writes:
 Ok, you got me.
 Didn't thought about friends of sub-classes.
 But in D I don't know ... maybe something similar is possible?
should it even be possible? does anyone write such code in practice? it looks confusing as hell to me.
Jun 14 2022
parent reply Dom Disc <dominikus scherkl.de> writes:
On Tuesday, 14 June 2022 at 22:08:31 UTC, Zoadian wrote:
 Ok, you got me.
 Didn't thought about friends of sub-classes.
 But in D I don't know ... maybe something similar is possible?
should it even be possible? does anyone write such code in practice? it looks confusing as hell to me.
It would become even more ugly if there are multiple private variables, because in that case you would need to put each of them in its own sub-class with its own set of friends. But the point is: in C++ it IS possible to encapsulate each variable so, that it can be accessed only by an explicitly defined set of functions (the friends of the subclass). This is today not possible in D. We can make it possible (and much less ugly) with two UDAs, one to hide the variables and one to explicitly allow access to specific variables. Of course we shouldn't name them like in my previous post. Better names would be hidden and sees(x, y, z). I think everybody able to speak english can easily guess what these should mean, even without reading the spec. Unlike hidden alone this allows us to do things that are currently impossible, so it brings real benefit.
Jun 14 2022
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 15 June 2022 at 06:55:35 UTC, Dom Disc wrote:
 On Tuesday, 14 June 2022 at 22:08:31 UTC, Zoadian wrote:
 Ok, you got me.
 Didn't thought about friends of sub-classes.
 But in D I don't know ... maybe something similar is possible?
should it even be possible? does anyone write such code in practice? it looks confusing as hell to me.
It would become even more ugly if there are multiple private variables, because in that case you would need to put each of them in its own sub-class with its own set of friends. But the point is: in C++ it IS possible to encapsulate each variable so, that it can be accessed only by an explicitly defined set of functions (the friends of the subclass). This is today not possible in D.
This isn't something you want to do frequently, but it makes sense in the rare case where you deal with deadlock issues or other dangerous things! :-) While module-based encapsulation is ok for modest complexity situations, it is sometimes useful to make everything object-private and then open up when you need it. I recently ported some big javascript thing to TypeScript and it was very useful to first convert to classes, then make all fields private first, then remove the privacy until the compilation was successful. That gave me a better understanding of what the structure was.
Jun 15 2022
prev sibling parent Zoadian <no no.no> writes:
On Wednesday, 15 June 2022 at 06:55:35 UTC, Dom Disc wrote:
 On Tuesday, 14 June 2022 at 22:08:31 UTC, Zoadian wrote:
 [...]
It would become even more ugly if there are multiple private variables, because in that case you would need to put each of them in its own sub-class with its own set of friends. [...]
please provide a real world example where this feature would be used, and there is no better option to structure your code.
Jun 15 2022
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 14 June 2022 at 17:16:04 UTC, Dom Disc wrote:
 On Tuesday, 14 June 2022 at 10:47:18 UTC, forkit wrote:
 Now I need a suitable, enforcable, design constraint, so i can 
 unfriend.
Yes, now we're talking. What we need is no new level of privacy, we need a method to unfriend something - especially applicable also to member functions. THIS would give us some real new benefit.
If a function doesn't need access to private member variables, don't implement it as a member function. Instead, put it in a separate module and call it using UFCS. https://www.ddj.com/cpp/how-non-member-functions-improve-encapsu/184401197
Jun 14 2022
parent reply Dom Disc <dominikus scherkl.de> writes:
On Tuesday, 14 June 2022 at 19:39:40 UTC, Paul Backus wrote:
 If a function doesn't need access to private member variables, 
 don't implement it as a member function. Instead, put it in a 
 separate module and call it using UFCS.
Yes, that is nice. But the most common usecase is that the class has multiple private variables, and each member function needs only access to some of them. Today there is no way to express to which of them a function should have access and to which not. My idea was the following: class C { private int _hidden_x; private int _hidden_y; limitPrivateAccess(_hidden_x) foo(x) { _hidden_x = x; _hidden_y = 0; // error: foo has no access to _hidden_y } } So foo would normally have access to _hidden_y although the developer doesn't want that. That is so because today _all_ member functions (and friends) have access to _all_ private variables. The new UDA limitPrivateAccess restrict this to only those private variables given as its parameters. Together with a new privacy-level " hidden" we could even have variables that no-one has access to, except those functions that are explicitly allowed to access them via the UDA. This would be the ultimate restriction level.
Jun 14 2022
next sibling parent reply Abdulhaq <alynch4047 gmail.com> writes:
On Tuesday, 14 June 2022 at 20:22:17 UTC, Dom Disc wrote:
 class C
 {
    private int _hidden_x;
    private int _hidden_y;
     limitPrivateAccess(_hidden_x) foo(x)
    {
       _hidden_x = x;
       _hidden_y = 0; // error: foo has no access to _hidden_y
    }
 }

 So foo would normally have access to _hidden_y although the 
 developer doesn't want that. That is so because today _all_ 
 member functions (and friends) have access to _all_ private 
 variables. The new UDA  limitPrivateAccess restrict this to 
 only those private variables given as its parameters.
 Together with a new privacy-level " hidden" we could even have 
 variables that no-one has access to, except those functions 
 that are explicitly allowed to access them via the UDA. This 
 would be the ultimate restriction level.
my mind is boggling LOL seriously though, the access restrictions must be declared by the provider, to limit the notional consumer. Here the provider is restricting itself, it's pointless.
Jun 15 2022
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 15.06.22 12:57, Abdulhaq wrote:
 On Tuesday, 14 June 2022 at 20:22:17 UTC, Dom Disc wrote:
 class C
 {
    private int _hidden_x;
    private int _hidden_y;
     limitPrivateAccess(_hidden_x) foo(x)
    {
       _hidden_x = x;
       _hidden_y = 0; // error: foo has no access to _hidden_y
    }
 }

 So foo would normally have access to _hidden_y although the developer 
 doesn't want that. That is so because today _all_ member functions 
 (and friends) have access to _all_ private variables. The new UDA 
  limitPrivateAccess restrict this to only those private variables 
 given as its parameters.
 Together with a new privacy-level " hidden" we could even have 
 variables that no-one has access to, except those functions that are 
 explicitly allowed to access them via the UDA. This would be the 
 ultimate restriction level.
my mind is boggling LOL seriously though, the access restrictions must be declared by the provider, to limit the notional consumer. Here the provider is restricting itself, it's pointless.
It's not pointless. It's automatically checked code documentation. There are surprisingly many vocal programmers who argue as if they never wrote software in a team (possibly with turnover).
Jun 25 2022
parent Adam Ruppe <destructionator gmail.com> writes:
On Sunday, 26 June 2022 at 00:44:48 UTC, Timon Gehr wrote:
 There are surprisingly many vocal programmers who argue as if 
 they never wrote software in a team (possibly with turnover).
It is difficult to work in a group when you're omnipotent.
Jun 25 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 20:22:17 UTC, Dom Disc wrote:
 On Tuesday, 14 June 2022 at 19:39:40 UTC, Paul Backus wrote:
 If a function doesn't need access to private member variables, 
 don't implement it as a member function. Instead, put it in a 
 separate module and call it using UFCS.
Yes, that is nice. But the most common usecase is that the class has multiple private variables, and each member function needs only access to some of them. Today there is no way to express to which of them a function should have access and to which not. My idea was the following: class C { private int _hidden_x; private int _hidden_y; limitPrivateAccess(_hidden_x) foo(x) { _hidden_x = x; _hidden_y = 0; // error: foo has no access to _hidden_y } } So foo would normally have access to _hidden_y although the developer doesn't want that. That is so because today _all_ member functions (and friends) have access to _all_ private variables. The new UDA limitPrivateAccess restrict this to only those private variables given as its parameters. Together with a new privacy-level " hidden" we could even have variables that no-one has access to, except those functions that are explicitly allowed to access them via the UDA. This would be the ultimate restriction level.
I kinda like this... just as an 'idea', at this stage. I'm certainly not suggesting we should do it. But discussions are always worthwhile. But some classes can indeed be very long....even necessarily so. I'd like the concept to make use of the existing invariants() method. i.e some attribute that can only be used, and only makes sense, when used in that method. the ultimate (and only) aim here, is to enhance the provability of the program, through static compile time checking (which can't be done unless you can first express intent). e.g: (and no. I haven't thought this through very much at all). class C { private(this): int x, y, z; invariant() { // restrict certain member functions to certain member variables. assert( restrictedMemberAccess {x, y : setXY, getX, getY}; } setXY(int x, int y) { x = x; y = y } // fine int getX( return x); // fine int getY( return y); // fine void foo( x = 0; ); // noCanDo! foo is not in the above list. void bar( z = 0; ); // fine. no invariants declared. so normal rules apply. } Destroy!
Jun 25 2022
parent forkit <forkit gmail.com> writes:
On Sunday, 26 June 2022 at 01:28:46 UTC, forkit wrote:

Here I introduce a new concept, which (for now), we'll call a 
'view'.

It can solve multiple problems.

First, it eliminated a need for 'private(this)'

Second, it allows fine grained control of member access, to 
member variables.

Anything declared private, in a view, is simply private to that 
view.


class myClass
{
      view
     {
         private:
           int x;

     	public:
           void setX(int x) { this.x = x; }
           int getX( return this.x; }
     }


     private:
       void fred() { this.x = -1; }  // error: fred is not part of 
the view that contains x
       int waldo() { return this.x; } // error: waldo is not part 
of the view that contains x

     public:
       void foo() { this.x = -1; }  // error: foo is not part of 
the view that contains x
       int bar() { return this.x; } // error: bar is not part of 
the view that contains x
}
Jun 25 2022
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
 Is the cost, the unjustified cognitive burden of having both 
 'private' and 'private(scope)', instead of just 'private'?

 Is the cost - it's just too complicated to change the compiler 
 source to accomodate this option?

 What do you think the cost of adding such a feature is?
The main cost is the opportunity cost [1]. Any effort we spend implementing, documenting, debugging, and teaching 'private(scope)' reduces the amount of effort we can spend on other things. Likewise, any effort new users learning D have to spend on learning 'private(scope)' reduces the amount of effort they can spend learning other parts of the language (or, for that matter, using D to solve their problems). So the relevant questions here are: 1. Among all of the possible improvements we could make to D, is this particular one the *best* use of our limited resources, as a community? 2. Among all of the additional language features we could ask new users of D to learn, will this particular one give them the *most* benefit for their effort? [1] https://en.wikipedia.org/wiki/Opportunity_cost
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 10:26:09 UTC, Paul Backus wrote:
 The main cost is the opportunity cost [1]. Any effort we spend 
 implementing, documenting, debugging, and teaching 
 'private(scope)' reduces the amount of effort we can spend on 
 other things. Likewise, any effort new users learning D have to 
 spend on learning 'private(scope)' reduces the amount of effort 
 they can spend learning other parts of the language (or, for 
 that matter, using D to solve their problems).
you mean, like mustuse ;-) a 'new' feature that I'll likely *never* have a need to use btw.
 So the relevant questions here are:

 1. Among all of the possible improvements we could make to D, 
 is this particular one the *best* use of our limited resources, 
 as a community?
You mean limited people working on the compiler? So if I paid someone to cover all the work associated with this, you'd be ok with it?
 2. Among all of the additional language features we could ask 
 new users of D to learn, will this particular one give them the 
 *most* benefit for their effort?

 [1] https://en.wikipedia.org/wiki/Opportunity_cost
again, I can come back to mustuse ;-) I can assure you, there is far more cognitive effort involved in understanding mustuse, than there is for understanding the difference between 'private' and private(scope)'. For those of us who can already declare scope private, the cognitivie effort is.. 0.000000000000000000000001% of the cognitive effort needed to understand mustuse.
Jun 14 2022
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Tuesday, 14 June 2022 at 10:54:17 UTC, forkit wrote:
 you mean, like  mustuse ;-)

 a 'new' feature that I'll likely *never* have a need to use btw.
I don't think you have bad intentions, but this comes across as passive-aggresive to me. Just wanted to let you know.
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 11:12:59 UTC, Dennis wrote:
 On Tuesday, 14 June 2022 at 10:54:17 UTC, forkit wrote:
 you mean, like  mustuse ;-)

 a 'new' feature that I'll likely *never* have a need to use 
 btw.
I don't think you have bad intentions, but this comes across as passive-aggresive to me. Just wanted to let you know.
My point was, that 'part' of the argument he put forward does not stand up to further scrutiny. Twisting that around to suggest I'm being passive-aggressive, is nonsense.
Jun 14 2022
parent reply Jordan Wilson <wilsonjord gmail.com> writes:
On Tuesday, 14 June 2022 at 22:26:18 UTC, forkit wrote:
 On Tuesday, 14 June 2022 at 11:12:59 UTC, Dennis wrote:
 On Tuesday, 14 June 2022 at 10:54:17 UTC, forkit wrote:
 you mean, like  mustuse ;-)

 a 'new' feature that I'll likely *never* have a need to use 
 btw.
I don't think you have bad intentions, but this comes across as passive-aggresive to me. Just wanted to let you know.
My point was, that 'part' of the argument he put forward does not stand up to further scrutiny. Twisting that around to suggest I'm being passive-aggressive, is nonsense.
In the link you posted about passive-aggressive behavior, there is the following section: 3. Diverting The Subject. You asked what the cost is of adding a 'private(scope)' feature. Paul then replied about opportunity costs. You then mentioned mustuse, in a way that could be construed as mildly disparaging regarding it's own opportunity cost, in order dismiss his answer as being valid. Dennis considered this passive-aggressive; he might be wrong, but not nonsensical. Personally, I'm more likely to use 'private(scope)' than mustuse. I'm also more likely to understand 'private(scope)' better than mustuse. These two facts have nothing to do with the question "does private(scope) justify the cost". Jordan
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 23:18:08 UTC, Jordan Wilson wrote:
 In the link you posted about passive-aggressive behavior, there 
 is the following section: 3. Diverting The Subject.

 You asked what the cost is of adding a 'private(scope)' feature.
 Paul then replied about opportunity costs.
 You then mentioned  mustuse, in a way that could be construed 
 as mildly disparaging regarding it's own opportunity cost, in 
 order dismiss his answer as being valid.
yes. I was indeed dismissing a 'part' of his argument as being invalid. but that's because *it was* invalid, and not because I was being passive-aggressive. that is the difference ;-) please review that part of his arguement again.
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 23:31:35 UTC, forkit wrote:
 please review that part of his arguement again.
to be specific, it was this part "The main cost is the opportunity cost [1]. Any effort we spend implementing, documenting, debugging, and teaching 'private(scope)' reduces the amount of effort we can spend on other things." That is not a valid argument against private(scope). It an argument against anything. I demonstrated how invalid this part of his argument is, by referring back to mustuse (his proposal). I need arguments against the idea being proposed, not any idea.
Jun 14 2022
next sibling parent forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 23:44:24 UTC, forkit wrote:
 ...
 That is not a valid argument against private(scope).

 It an argument against anything.
indeed he acknowledged as such in his response: "Sure, you could make an argument that the effort spent on mustuse could have been better spent elsewhere."
Jun 14 2022
prev sibling parent reply Jordan Wilson <wilsonjord gmail.com> writes:
On Tuesday, 14 June 2022 at 23:44:24 UTC, forkit wrote:
 On Tuesday, 14 June 2022 at 23:31:35 UTC, forkit wrote:
 please review that part of his arguement again.
to be specific, it was this part "The main cost is the opportunity cost [1]. Any effort we spend implementing, documenting, debugging, and teaching 'private(scope)' reduces the amount of effort we can spend on other things." That is not a valid argument against private(scope). It an argument against anything. I demonstrated how invalid this part of his argument is, by referring back to mustuse (his proposal). I need arguments against the idea being proposed, not any idea.
Given that 'opportunity cost' is mentioned as the main cost, implies that Paul found nothing technically wrong this new feature; if the idea was unsound etc., I'm sure that it would have been mentioned before this. Given that 'opportunity cost' was explicitly mentioned (which as you say, is a self-evident cost for any new feature), implies that he believes that the opportunity cost of this nothing-wrong-in-principle private(scope) feature is too high. I really can't see how mustuse is relevant to private(scope) benefit-to-cost ratio, beyond the "well, mustuse got in, so there's no reason for private(scope) not to get in" type argument...but maybe that's just me not understanding the connection. Jordan
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 03:01:19 UTC, Jordan Wilson wrote:
 On Tuesday, 14 June 2022 at 23:44:24 UTC, forkit wrote:
 On Tuesday, 14 June 2022 at 23:31:35 UTC, forkit wrote:
 please review that part of his arguement again.
to be specific, it was this part "The main cost is the opportunity cost [1]. Any effort we spend implementing, documenting, debugging, and teaching 'private(scope)' reduces the amount of effort we can spend on other things." That is not a valid argument against private(scope). It an argument against anything. I demonstrated how invalid this part of his argument is, by referring back to mustuse (his proposal). I need arguments against the idea being proposed, not any idea.
Given that 'opportunity cost' is mentioned as the main cost, implies that Paul found nothing technically wrong this new feature; if the idea was unsound etc., I'm sure that it would have been mentioned before this. Given that 'opportunity cost' was explicitly mentioned (which as you say, is a self-evident cost for any new feature), implies that he believes that the opportunity cost of this nothing-wrong-in-principle private(scope) feature is too high. I really can't see how mustuse is relevant to private(scope) benefit-to-cost ratio, beyond the "well, mustuse got in, so there's no reason for private(scope) not to get in" type argument...but maybe that's just me not understanding the connection. Jordan
Yes. I want to know what is technically wrong with private(scope). then I can attempt to address that concern. If we establish that nothing is technically wrong (in terms of the cost of implementing it in particular), and, we establish that it's a useful idea, then we can move to the issue of prioritising the addition of this feature over that feature. It's not that this point is not relevant, its just not relevant at this stage. This starting to sound like a nice diversion tactic to me ;-)
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 03:10:32 UTC, forkit wrote:

oh. I just finally got swift working on windows..took way more 
effort than I anticipated :-(

so that's where my attention will be for a while..

I'm sure many will be happy to hear this ;-)
Jun 14 2022
parent reply forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 03:28:10 UTC, forkit wrote:

The fact is, this idea has no chance of ever being in D, as 
Walter is too stuck in his way, and forces OO programmers to 
fully surrender the encapsulation of a class, to the module. It's 
just a ridiculous demand.

The approriate response, would be, let's compromise... here's a 
feature that does exactly what you need, and doesn't impact those 
who don't need it.

But no... too stubborn.

That's the cause of the controversy. Not the idea. The idea will 
continue to pop up... the same response will come from Walter, 
and around..and around... we go....

I'm getting off ;-)

Bye!
Jun 14 2022
parent zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 05:55:29 UTC, forkit wrote:

 I'm getting off ;-)

 Bye!
Don't hurry to leave, you can `fork it`! Change the `'d'` source code yourself! then, we have a new `'d'` compiler!
Jun 14 2022
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 14 June 2022 at 10:54:17 UTC, forkit wrote:
 On Tuesday, 14 June 2022 at 10:26:09 UTC, Paul Backus wrote:
 The main cost is the opportunity cost [1]. Any effort we spend 
 implementing, documenting, debugging, and teaching 
 'private(scope)' reduces the amount of effort we can spend on 
 other things. Likewise, any effort new users learning D have 
 to spend on learning 'private(scope)' reduces the amount of 
 effort they can spend learning other parts of the language 
 (or, for that matter, using D to solve their problems).
you mean, like mustuse ;-) a 'new' feature that I'll likely *never* have a need to use btw.
Sure, you could make an argument that the effort spent on mustuse could have been better spent elsewhere. The main difference between mustuse and private(scope) is that mustuse was *impossible* to simulate using existing language features, whereas private(scope) can be simulated by extracting the relevant code into its own dedicated module. I understand that you have reasons for disliking this workaround, but the fact that a workaround exists is still relevant when determining what ought to be prioritized. In any case, if you want to write a DIP, please don't let me stop you. The people you have to convince are Walter and Atila, not me.
Jun 14 2022
next sibling parent forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 11:22:58 UTC, Paul Backus wrote:
 On Tuesday, 14 June 2022 at 10:54:17 UTC, forkit wrote:
 On Tuesday, 14 June 2022 at 10:26:09 UTC, Paul Backus wrote:
 The main cost is the opportunity cost [1]. Any effort we 
 spend implementing, documenting, debugging, and teaching 
 'private(scope)' reduces the amount of effort we can spend on 
 other things. Likewise, any effort new users learning D have 
 to spend on learning 'private(scope)' reduces the amount of 
 effort they can spend learning other parts of the language 
 (or, for that matter, using D to solve their problems).
you mean, like mustuse ;-) a 'new' feature that I'll likely *never* have a need to use btw.
Sure, you could make an argument that the effort spent on mustuse could have been better spent elsewhere. The main difference between mustuse and private(scope) is that mustuse was *impossible* to simulate using existing language features, whereas private(scope) can be simulated by extracting the relevant code into its own dedicated module. I understand that you have reasons for disliking this workaround, but the fact that a workaround exists is still relevant when determining what ought to be prioritized.
yes. so I covered this in my initial post: --- "The next response, is that if you need this feature, then you can 'simulate it' by putting the class that needs this feature, into its own module. However, the one-class-per-module approach, imposes its own new design constraint, and not one the programmer necessarily makes of his/her own volition. It also does not necessarily follow, that a class in its own module, is there for the purposes of stipulating this constraint. There are any number of a reason, why a class might be put into its own module. You cannot infer anything from that. You'd have to speak the designer to know intent." ---
 In any case, if you want to write a DIP, please don't let me 
 stop you. The people you have to convince are Walter and Atila, 
 not me.
I'm not at that stage yet. I more interested in knowing what the others think about it. I already know what 'core' think about it ;-)
Jun 14 2022
prev sibling next sibling parent reply The Zealot <zod zod.zod> writes:
 The main difference between  mustuse and private(scope) is that 
  mustuse was *impossible* to simulate using existing language 
 features, whereas private(scope) can be simulated by extracting 
 the relevant code into its own dedicated module. I understand 
 that you have reasons for disliking this workaround, but the 
 fact that a workaround exists is still relevant when 
 determining what ought to be prioritized.
I don't think calling it a workaround is even correct. _class private_ would actually be the workaround. Just to put multiple classes inside one file that should conceptually not be in the same file in the first place.
Jun 14 2022
parent forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 12:00:29 UTC, The Zealot wrote:
 I don't think calling it a workaround is even correct.
 _class private_ would actually be the workaround. Just to put 
 multiple classes inside one file that should conceptually not 
 be in the same file in the first place.
why would you "put multiple classes inside one file that should conceptually not be in the same file in the first place. "? that makes no sense?? Also, I come from a world where if something should be private, you should be able to declare it as private. It's a clear principle in the languages I use. private is design tool to aid encapsulation, and makes it hard to accidently get it wrong. it's a feature I use all the time, for (primarily) those reasons just stated. barrier of encapsulation would be widened, not lessened, and accidental mistakes will occur all the time. without the feature I'm suggesting, you end up with what you already have in D. That is, you cannot use private to aid encapsulation *within* a module, nor can you use it prevent you (or others) from getting it wrong. since it doesn't exist! you have to rely on yourself in D, to 'just not do it' - (it's a C like mentality - which some are truly eager to protect as an important part of the indentity of the D programmer). I get it, but that just doesn't scale very well. you can't rely on every programmer on your project to 'just not do it'. The problem, once you want to scale software design, is not 'having' scope level private, it's 'not having it' - and the (primary) problems are as I've highlighted above. There is no downside to better encapsulation within a module, nor is there any downside to preventing accidental mistakes - unless you want neither of these things. I'd also like to be able to better enscapsulate ideas that already exist within a module, by being able to spread that module over more than one file. but that's a topic for another thread ;-)
Jun 14 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Tuesday, 14 June 2022 at 11:22:58 UTC, Paul Backus wrote:
 ...
 Sure, you could make an argument that the effort spent on 
  mustuse could have been better spent elsewhere.

 The main difference between  mustuse and private(scope) is that 
  mustuse was *impossible* to simulate using existing language 
 features, whereas private(scope) can be simulated by extracting 
 the relevant code into its own dedicated module. I understand 
 that you have reasons for disliking this workaround, but the 
 fact that a workaround exists is still relevant when 
 determining what ought to be prioritized.
I don't accept this argument either, because to 'simulate' private(scope) using the one-class-per-file approach, you must be willing to accept a considerable design constraint - i.e. one-class-per-module. The cost of simulating, is too high. that is my point here. It's not about disliking the workaround suggestion. It's about the cost of doing it. Also, it's not actually simulating private(scope) anyway, not by any stretch of the imagination, since there is no other code besides the class, in that file. It's just a workaround to avoid the need for private(scope), but at a considerable cost to the design choice you're then forced to accept in return. To take a qoute of the internet: "Having 17k line classes can be confusing, 17k line files with 170 classes in it can be confusing, having 170 classes in 170 files can be confusing.".
Jun 14 2022
parent zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 02:10:26 UTC, forkit wrote:
 having 170 classes in 170 files can be confusing.
No! It is best to put `all modules` in one file! Everyone visits from here. There is no need for `private`! Easier! Larger `encapsulation` are better! yes! `one file` for all!!!
Jun 14 2022
prev sibling next sibling parent reply Chris Katko <ckatko gmail.com> writes:
On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
 So there has been extensive discussions in other threads, 
 around the idea of adding a new 'design constraint feature' to 
 the D programming language.

 The design constraint feature, is 'designed' to allow the 
 programmer to make an explicit declaration, that some aspect of 
 the design of a class, should be private to that class, and 
 thereby make that aspect of the class (logically) inaccessible 
 to code outside of that class, but in the same module.

 The constraint could, in theory, apply to other types such as 
 struct or enum. But the suggestion currently relates to the 
 class type only.

 The below example compiles just fine, as you would expect.

 // ------
 module test;
  safe:

 class someClass
 {
     private:
         string _id;

     public:
         void setID(string id)
         {
             // some condition(s), if met, then:
             _id = id;
         }
 }

 unittest
 {
     someClass myclass = new someClass();
     myclass.setID("123");
 }

 // -----

 Is the above code consistent with the design intent of 
 someClass?

 The answer must be yes, since in D, private is private to the 
 module.

 But what if the intent was to require other code to 'use the 
 inteface' to access x?

 The problem is, many coming to D, come from languages where you 
 can already declare such an intent, and equally importantly, 
 have that intent enforced by the compiler, at compile time.

 But the D programming language has no feature to declare such 
 an intent. So where does this leave those programmers?

 The argument has been made, that D does not need such a 
 feature, because scope is always at the module level.

 But it does not follow, that scope at the module level 
 eliminates the need for such a feature. That argument is not 
 logical.

 The next response, is that if you need this feature, then you 
 can 'simulate it' by putting the class that needs this feature, 
 into its own module.

 However, the one-class-per-module approach, imposes its own new 
 design constraint, and not one the programmer necessarily makes 
 of his/her own volition.

 It also does not necessarily follow, that a class in its own 
 module, is there for the purposes of stipulating this 
 constraint.

 There are any number of a reason, why a class might be put into 
 its own module. You cannot infer anything from that. You'd have 
 to speak the designer to know intent.

 Other arguments have also been made against adding such a 
 feature, but it is difficult to take them seriously - such as 
 'why would a class ever need to hide something'.

 Now the advantage of adding such a feature, is that it provides 
 private at the scope level for those who want or expect such a 
 feature, it provides evidence of the designers intent to 
 separate implementations from interface, and the compiler which 
 now knows the intent, can enforce that intent, at compile time.

 So the only logical outcome of this discussion, is whether the 
 benefit of adding a design constraint *option* to the language, 
 outweighs the cost of adding it to the langauge.

 The benefits of adding this feature appear to be self-evident.

 So ultimately, this comes down to a benefit-vs-cost 
 consideration.

 The cost of adding it to the language, is less self-evident.

 Is the cost, the unjustified cognitive burden of having both 
 'private' and 'private(scope)', instead of just 'private'?

 Is the cost - it's just too complicated to change the compiler 
 source to accomodate this option?

 What do you think the cost of adding such a feature is?
I just want to +1 this. Even if I had to use a compiler switch. 'private' exists in many languages and has survived the test of time. Just because you don't use it doesn't mean other people don't--especially with D's bias toward gigantic 3000+ line module files. And if you don't like it, I don't see why you'd be suffering when it's an opt-in feature and you can just not use it. I find that private makes for a great way for rapid incremental development (that D is great at). You get things working, then "private" them, and immediately all references to that variable, function, or "hidden thing" are now visible as compiler errors that you can go down the line and fix. It's not "opt in" (the way error correction is supposed to be--opt-out so you cannot accidentally miss it). There's no possibility of human error in the list. If you make an outside reference illegal, it's now visible to the compiler and you. You can private members and fields, as often or rarely as you want. One at a time, clean up some references, then another one. The "alternative" is either do some gymnastics with entire classes moving around files to poorly emulate private, or, rename your interface variable/method in question which highlights all references to it as an error. Except that also includes CORRECT references in the list! You don't want to use it in the standard library, go ahead. But that doesn't make it not useful. By that logic, I guess we should rip out BetterC.
Jun 14 2022
parent The Zealot <zod zod.zod> writes:
On Tuesday, 14 June 2022 at 13:55:57 UTC, Chris Katko wrote:
 On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
 [...]
I just want to +1 this. Even if I had to use a compiler switch. 'private' exists in many languages and has survived the test of time. Just because you don't use it doesn't mean other people don't--especially with D's bias toward gigantic 3000+ line module files. And if you don't like it, I don't see why you'd be suffering when it's an opt-in feature and you can just not use it. [...]
you can do that already too. move the class to it's own module and mark members as public. then one at a time, turn them into private one by one. and you'll end up with the class in it's own module, where it actually belongs.
Jun 14 2022
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
 What do you think the cost of adding such a feature is?
Any cost above 0 is a no go here. The feature is useless. If things shouldn't see each other's private, they don't belong in the same module. Done, thanks for coming to my TED talk.
Jun 14 2022
next sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Tuesday, 14 June 2022 at 20:27:23 UTC, deadalnix wrote:
 On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
 What do you think the cost of adding such a feature is?
Any cost above 0 is a no go here. The feature is useless. If things shouldn't see each other's private, they don't belong in the same module. Done, thanks for coming to my TED talk.
The argument is useless because it is not even an argument.
Jun 14 2022
prev sibling parent reply zjh <fqbqrr 163.com> writes:
On Tuesday, 14 June 2022 at 20:27:23 UTC, deadalnix wrote:

 The feature is useless.
What is `useless` to you does not mean that it is useless to `others`. Many languages are `useless` to me. Shouldn't they exist? If the D language cannot become `more complex`, `c++` will devour you! Then people will go to `'c++'`. while the `d` community is getting smaller and smaller!
Jun 14 2022
parent reply zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 00:49:53 UTC, zjh wrote:

 If the D language cannot become `more complex`, `c++` will 
 devour you!
To become a real `"universal" system` language, D has to learn from `"c++"` and become more `complex`! Otherwise, you can not `meet the needs` of others!
Jun 14 2022
parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 15 June 2022 at 01:13:47 UTC, zjh wrote:
 On Wednesday, 15 June 2022 at 00:49:53 UTC, zjh wrote:

 If the D language cannot become `more complex`, `c++` will 
 devour you!
To become a real `"universal" system` language, D has to learn from `"c++"` and become more `complex`! Otherwise, you can not `meet the needs` of others!
c++ is more compadable with c and got a head start in templates Id suggest fixing ancient template bugs and getting several competing compilers going to compete with c++;
Jun 14 2022
parent reply zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 01:21:51 UTC, monkyyy wrote:

 Id suggest fixing ancient template bugs and getting several 
 competing compilers going to compete with c++;
In any case, we should not be afraid of `change`! not be afraid of `complexity`! Take a look at `'rust'`. It is becoming more and more `complex`. Take a look at `other mainstream languages`. Which is not `complex`? `C++23, c++26` is absolutely monsters! But people don't care!
Jun 14 2022
next sibling parent zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 01:57:28 UTC, zjh wrote:

 `C++23, c++26` is absolutely monsters! But people don't care!
Just like `VIM`, I `use and learn` it at the same time! I don't care how complicated it is! I don't care, as long as it can solve `my problem`! `D` can also add `new functions`! I hate stagnant language! I hate languages that don't update! e.g. I have been using the latest `C++` features!
Jun 14 2022
prev sibling next sibling parent reply norm <norm.rowtree gmail.com> writes:
On Wednesday, 15 June 2022 at 01:57:28 UTC, zjh wrote:
 On Wednesday, 15 June 2022 at 01:21:51 UTC, monkyyy wrote:

 Id suggest fixing ancient template bugs and getting several 
 competing compilers going to compete with c++;
In any case, we should not be afraid of `change`! not be afraid of `complexity`! Take a look at `'rust'`. It is becoming more and more `complex`. Take a look at `other mainstream languages`. Which is not `complex`? `C++23, c++26` is absolutely monsters! But people don't care!
I find C++ is getting easier to use with each release. Bring on C++23,26,... because each release adds new features that make using C++ that much easier use correctly and harder to use incorrectly. D's only real problem is people power. That will not be fixed by the constant bickering seen on these forums, it just drives potential developers away if anything. I said it before, instead of worrying about private, which TBH is a tiny issue because what is there now works reliably and well for 99% of code, maybe help D progress with actions not words. If you're not a compiler dev there are many other items that need work, help out testing compiler releases and submitting bugs, help out with ecosystem and tooling, package management etc.
Jun 14 2022
next sibling parent reply zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 02:15:16 UTC, norm wrote:

 If you're not a compiler dev there are many other items that 
 need work, help out testing compiler releases and submitting 
 bugs, help out with ecosystem and tooling, package management 
 etc.
The fundamental problem of `D` language is the problem of `thinking`! They are circling the `wrong path`! There is something wrong with the way `they think`! There is something wrong with `strategy`. No amount of `tactics` can make up for it!
Jun 14 2022
parent reply zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 02:20:43 UTC, zjh wrote:

It is necessary to `quarrel`, but the `'d'` official doesn't know 
what is `important` and what is not!
There is something wrong with `their way of thinking`!
Jun 14 2022
parent zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 02:23:31 UTC, zjh wrote:

 There is something wrong with `their way of thinking`!
As I said, `the smaller` the encapsulation, the better! This is `principle`! This is the most `basic 'principle'` issue, but basically no one thinks it is `important`! This is very funny! Road is wrong. The harder you work, the more wrong you are!
Jun 14 2022
prev sibling next sibling parent reply forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 02:15:16 UTC, norm wrote:
 On Wednesday, 15 June 2022 at 01:57:28 UTC, zjh wrote:
 On Wednesday, 15 June 2022 at 01:21:51 UTC, monkyyy wrote:

 Id suggest fixing ancient template bugs and getting several 
 competing compilers going to compete with c++;
In any case, we should not be afraid of `change`! not be afraid of `complexity`! Take a look at `'rust'`. It is becoming more and more `complex`. Take a look at `other mainstream languages`. Which is not `complex`? `C++23, c++26` is absolutely monsters! But people don't care!
I find C++ is getting easier to use with each release. Bring on C++23,26,... because each release adds new features that make using C++ that much easier use correctly and harder to use incorrectly. D's only real problem is people power. That will not be fixed by the constant bickering seen on these forums, it just drives potential developers away if anything. I said it before, instead of worrying about private, which TBH is a tiny issue because what is there now works reliably and well for 99% of code, maybe help D progress with actions not words.
That's cause D still very much operates in the small (in more than one way). languages that have this feature, operate in the large. when you operate in the large, tighter encapsulation, explicit intent, enforceable design, become very important aspects in developing correct code. when you operate in the small, these matter a lot less - and so they'll be seen as unnecssary, constraining, and unwelcome, and often result in bickering, as you say. A lot of this controversy comes back to Walters firm view, that 'the module' is the unit of encapsulation in D, 'and that's all there is too it' attitude. Of course, anyone from OOP will know that a class is a very important unit of encapsulation in its own right. What Walter fails to acknowledge in this 'firm view' (apart from the above), is that encapsulation is actually an abstract concept that can apply at any level whatsoever, including at the level of module-level-components (code inside a module). Indeed most code within a module is already encapsulated in some way (by the code itself, not the module). A function is encapsulated. An enum is encapsulated. Even an int is encapsulated. A class is encapsulated .. well... actually, no.. it isn't. No in D. You can't do it.
Jun 14 2022
parent forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 02:53:32 UTC, forkit wrote:

for an OO programmer, coming to D, to delegate its encapsulation 
to the module, is an antipattern.

no wonder is causes some much controversy.

delegate a classes encapsulation to the module will come back to 
haunt him/her... and likely anyone that uses or maintains that 
code.

I'd recommend OO programmers consider very carefully, whether D 
is an appropriate choice of language.
Jun 14 2022
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 15 June 2022 at 02:15:16 UTC, norm wrote:
 D's only real problem is people power.
This is a not true at all. D would end up in the same position no matter how many people you throw at it. You first need to: 1. set clear goals 2. design an architecture that makes the goals achievable and the product maintainable 3. set up an iterative process that provide a clear path to the goals 4. evaluate and improve the process D has both a formal and informal process, but the informal one trumphs the formal one. Then you either need to break up the culture and enforce the formal process or you need to change the formal one to match the informal process and improve on it from there. So there are two realistic options: A. View dmd as legacy and switch focus to SDC or some other clean slate approach, help out by setting clear goals, create a documented architecture, set up an iterative process. B. Adopt the informal process for dmd, and modify it by creating a clear separation between people who create and people who do quality assurance. Give the latter team full veto power. Then create a plan for giving dmd an architecture. Option A is probably easier and cheaper.
Jun 14 2022
next sibling parent reply test123 <test123 gmail.com> writes:
On Wednesday, 15 June 2022 at 06:26:51 UTC, Ola Fosheim Grøstad 
wrote:
 On Wednesday, 15 June 2022 at 02:15:16 UTC, norm wrote:
 D's only real problem is people power.
This is a not true at all. D would end up in the same position no matter how many people you throw at it. You first need to: 1. set clear goals 2. design an architecture that makes the goals achievable and the product maintainable 3. set up an iterative process that provide a clear path to the goals 4. evaluate and improve the process
This sound good, but not must be this way. In my humble opinion, D lake of good betterC library creator. With current betterC status, it can do so much more than C. There is a few like mir and d-uring. BetterC has problem, but much stable compare to Druntime if you build up your own std base on it. It also generate much more higher performance code compare Druntmime with exception.
Jun 15 2022
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 15 June 2022 at 07:04:39 UTC, test123 wrote:
 This sound good, but not must be this way.

 In my humble opinion, D lake of good betterC library creator.

 With current betterC status, it can do so much more than C. 
 There is a few like mir and d-uring.

 BetterC has problem, but much stable compare to Druntime if you 
 build up your own std base on it. It also generate much more 
 higher performance code compare Druntmime with exception.
Yes, you could also scale down and reduce the scope to "betterC". But as long as adding features is important you have to change the process/architecture.
Jun 15 2022
prev sibling next sibling parent forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 06:26:51 UTC, Ola Fosheim Grøstad 
wrote:
 So there are two realistic options:

 A. View dmd as legacy and switch focus to SDC or some other 
 clean slate approach, help out by setting clear goals, create a 
 documented architecture, set up an iterative process.

 B. Adopt the informal process for dmd, and modify it by 
 creating a clear separation between people who create and 
 people who do quality assurance. Give the latter team full veto 
 power. Then create a plan for giving dmd an architecture.

 Option A is probably easier and cheaper.
or... https://youtu.be/43sjym5ZS68?t=1428
Jun 15 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 06:26:51 UTC, Ola Fosheim Grøstad 
wrote:
 So there are two realistic options:

 A. View dmd as legacy and switch focus to SDC or some other 
 clean slate approach, help out by setting clear goals, create a 
 documented architecture, set up an iterative process.

 B. Adopt the informal process for dmd, and modify it by 
 creating a clear separation between people who create and 
 people who do quality assurance. Give the latter team full veto 
 power. Then create a plan for giving dmd an architecture.

 Option A is probably easier and cheaper.
btw. what is this SDC thing? Is it a D compiler? Does it inherit all the problems of the current compiler, or is it 'more modular', like the approach LLVM have taken, so that more people can work on it? I'm doubt that another monolithic compiler, will solve very much at all. They just quickly reach a point where they're too complex, and nobody dares touch it.
Jun 15 2022
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 15 June 2022 at 07:40:37 UTC, forkit wrote:
 btw. what is this SDC thing?

 Is it a D compiler?
That seems to be the long term goal: https://github.com/snazzy-d/SDC
 Does it inherit all the problems of the current compiler, or is 
 it 'more modular', like the approach LLVM have taken, so that 
 more people can work on it?
I believe it is done 100% from scratch, so I would expect it to be layered and modular, but I am not involved with it. I would expect the architecture to evolve at such an early stage, so I assume that those who engage with it can improve on the architectural design, but I assume you would have to ask the people who are actively pursuing it to get real answers.
Jun 15 2022
parent reply forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 07:57:12 UTC, Ola Fosheim Grøstad 
wrote:
 On Wednesday, 15 June 2022 at 07:40:37 UTC, forkit wrote:
 btw. what is this SDC thing?

 Is it a D compiler?
That seems to be the long term goal: https://github.com/snazzy-d/SDC
well i wish em' luck. D will need it. I'm now enjoying using Swift way more than D. So that's it for me.
Jun 15 2022
parent reply Abdulhaq <alynch4047 gmail.com> writes:
On Wednesday, 15 June 2022 at 11:06:45 UTC, forkit wrote:
 I'm now enjoying using Swift way more than D.

 So that's it for me.
I guarantee you'll be back within the month, the D forums are addictive. Even Chris has not escaped. Paulo is still here. Only bearophile is running free.
Jun 15 2022
next sibling parent reply bauss <jj_1337 live.dk> writes:
On Wednesday, 15 June 2022 at 11:16:42 UTC, Abdulhaq wrote:
 On Wednesday, 15 June 2022 at 11:06:45 UTC, forkit wrote:
 I'm now enjoying using Swift way more than D.

 So that's it for me.
I guarantee you'll be back within the month, the D forums are addictive. Even Chris has not escaped. Paulo is still here. Only bearophile is running free.
You can be active in the forum without actually coding in D.
Jun 15 2022
parent reply Abdulhaq <alynch4047 gmail.com> writes:
On Wednesday, 15 June 2022 at 11:34:55 UTC, bauss wrote:
 On Wednesday, 15 June 2022 at 11:16:42 UTC, Abdulhaq wrote:
 On Wednesday, 15 June 2022 at 11:06:45 UTC, forkit wrote:
 I'm now enjoying using Swift way more than D.

 So that's it for me.
I guarantee you'll be back within the month, the D forums are addictive. Even Chris has not escaped. Paulo is still here. Only bearophile is running free.
You can be active in the forum without actually coding in D.
You're right of course but I think D users get annoyed to see a lot of 'noise' from non-users (understandably). On a serious note, does anyone know what happened to Jonathan M. Davies? His voice is missed around here. I fear the worst.
Jun 15 2022
parent reply bauss <jj_1337 live.dk> writes:
On Wednesday, 15 June 2022 at 11:55:15 UTC, Abdulhaq wrote:
 You're right of course but I think D users get annoyed to see a 
 lot of 'noise' from non-users (understandably). On a serious 
 note, does anyone know what happened to Jonathan M. Davies? His 
 voice is missed around here. I fear the worst.
Thinking of it then I actually haven't seen him post or answer anything in a very long time. I'm going to just assume that he either moved on from D, has been very busy etc. rather than something negative :) His Github seems to have been inactive since 2020 however, or at least with very minor contributions (7 only.) Nothing new on LinkedIn either, or at least not since 2017 I think. Also his website/blog or whatever is the same. Also he hasn't been active on stackoverflow in at least 2 years. Sort of strange, but people come and go from websites and communities all the times without it being something super bad. I'll admit the timing is strange however.
Jun 15 2022
parent reply Mike Parker <aldacron gmail.com> writes:
On Wednesday, 15 June 2022 at 12:11:02 UTC, bauss wrote:

 Thinking of it then I actually haven't seen him post or answer 
 anything in a very long time.

 I'm going to just assume that he either moved on from D, has 
 been very busy etc. rather than something negative :)
Johnathan hasn't moved on. I spoke with him a couple of months back and he is hoping to get back to it eventually. I'll leave it to him to provide more information than that.
Jun 15 2022
next sibling parent bauss <jj_1337 live.dk> writes:
On Wednesday, 15 June 2022 at 12:54:10 UTC, Mike Parker wrote:
 On Wednesday, 15 June 2022 at 12:11:02 UTC, bauss wrote:

 Thinking of it then I actually haven't seen him post or answer 
 anything in a very long time.

 I'm going to just assume that he either moved on from D, has 
 been very busy etc. rather than something negative :)
Johnathan hasn't moved on. I spoke with him a couple of months back and he is hoping to get back to it eventually. I'll leave it to him to provide more information than that.
Yes, that's why I also added "has been very busy" :) Glad to know that he's not just gone however.
Jun 15 2022
prev sibling parent Abdulhaq <alynch4047 gmail.com> writes:
On Wednesday, 15 June 2022 at 12:54:10 UTC, Mike Parker wrote:
 On Wednesday, 15 June 2022 at 12:11:02 UTC, bauss wrote:

 Thinking of it then I actually haven't seen him post or answer 
 anything in a very long time.

 I'm going to just assume that he either moved on from D, has 
 been very busy etc. rather than something negative :)
Johnathan hasn't moved on. I spoke with him a couple of months back and he is hoping to get back to it eventually. I'll leave it to him to provide more information than that.
Good to know, thanks Mike.
Jun 15 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Wednesday, 15 June 2022 at 11:16:42 UTC, Abdulhaq wrote:
 On Wednesday, 15 June 2022 at 11:06:45 UTC, forkit wrote:
 I'm now enjoying using Swift way more than D.

 So that's it for me.
I guarantee you'll be back within the month, the D forums are addictive. Even Chris has not escaped. Paulo is still here. Only bearophile is running free.
I'm back! But not for long ;-) Just want to mention this, as it's seem pretty relevant: So I found this discussion from 2003! That's (at least) how long this has been going on. It will continue to go on of course, because there is no right or wrong way here. The only genuine solution to this problem is providing 'a choice' that the programmer can make. Sean L. Palmer : "I find that it's one of the biggest pains in programming, deciding what to make private, what to encapsulate, what to expose." Ken Carpenter : "If you want something to be made accessible to others, then is it really so hard to type "public"? Both perspective seem reasonable to me. Walters response is interesting, and (of course) it still hasn't changed - i.e. -> basically (paraphrased) 'if you want to program in D, you gotta do it my way'. In the end though, the controversy continues, not because of Sean or Ken's position, but because Walter is just too stubborn to compromise so that both Sean and Ken can both do what they think is best for their design. In a compromise, nobody loses. The problem here is not Sean's or Ken's view/perspective. The problem is Walter. (and those that support his view of -> 'NO COMPROMISE!' https://forum.dlang.org/post/b186be$udr$1 digitaldaemon.com
Jun 15 2022
next sibling parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 00:02:41 UTC, forkit wrote:

oops:

https://forum.dlang.org/thread/b12n5o$1lvn$1 digitaldaemon.com?page=1
Jun 15 2022
parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 00:06:14 UTC, forkit wrote:

see .. the world does not come crashing down, simply because you 
can declare something private ;-)


(in Swift)

// -----------
struct A
{
   private static var x = 100;
   fileprivate static var z = 200;
}

//print(A.x); //  error: 'x' is inaccessible due to 'private' 
protection level
print(A.z); // ok

// -----------
Jun 15 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 01:04:22 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 00:06:14 UTC, forkit wrote:

 see .. the world does not come crashing down, simply because 
 you can declare something private ;-)


 (in Swift)

 // -----------
 struct A
 {
   private static var x = 100;
   fileprivate static var z = 200;
 }

 //print(A.x); //  error: 'x' is inaccessible due to 'private' 
 protection level
 print(A.z); // ok

 // -----------
Swift has 5 different access control modes: - private: as in C++ - file private: for the source file - internal: for a collection of sources files constituting a module - open access: allows subclassing and override outside the module - public: … Swift also does some conservative analysis of references, preventing writing to references if there is an alias that would make it a conflict: https://docs.swift.org/swift-book/LanguageGuide/MemorySafety.html
Jun 16 2022
parent forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 07:16:56 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 16 June 2022 at 01:04:22 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 00:06:14 UTC, forkit wrote:

 see .. the world does not come crashing down, simply because 
 you can declare something private ;-)


 (in Swift)

 // -----------
 struct A
 {
   private static var x = 100;
   fileprivate static var z = 200;
 }

 //print(A.x); //  error: 'x' is inaccessible due to 'private' 
 protection level
 print(A.z); // ok

 // -----------
Swift has 5 different access control modes: - private: as in C++ - file private: for the source file - internal: for a collection of sources files constituting a module - open access: allows subclassing and override outside the module - public: … Swift also does some conservative analysis of references, preventing writing to references if there is an alias that would make it a conflict: https://docs.swift.org/swift-book/LanguageGuide/MemorySafety.html
yes, in essence, the everything is global in a Swift module, much like like D (at least conceptually). Although the module concept is different in Swift (being a bunch of file that make up module - which i like much better than the D concept). So Swift provides that same convenience as D, of not having to state anything, and just go about writing code, if that's your style. But it allows people to 'choose' a style -> private (scope private), and fileprivate (private to the file). I mean, choice is good right? Well, I like it anyway.
Jun 16 2022
prev sibling next sibling parent zjh <fqbqrr 163.com> writes:
On Thursday, 16 June 2022 at 00:02:41 UTC, forkit wrote:
 but because Walter is just too stubborn to compromise so that 
 both Sean and Ken can both do what they think is best for their 
 design.
They only see that "public" is very useful, but they don't see that real "private" is also very useful.
Jun 15 2022
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
On Thursday, 16 June 2022 at 00:02:41 UTC, forkit wrote:
 Sean L. Palmer : "I find that it's one of the biggest pains in 
 programming, deciding what to make private, what to 
 encapsulate, what to expose."
Incapsulation is overrated, so it's really a non issue, maybe only if you treat incapsulation as a superidea, but D doesn't honor superideas, it's a practical language. Also memoization is a use case for varying access between different methods of the same class. Would you address that too?
Jun 16 2022
next sibling parent forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 07:45:52 UTC, Kagamin wrote:
 On Thursday, 16 June 2022 at 00:02:41 UTC, forkit wrote:
 Sean L. Palmer : "I find that it's one of the biggest pains in 
 programming, deciding what to make private, what to 
 encapsulate, what to expose."
Incapsulation is overrated, so it's really a non issue, maybe only if you treat incapsulation as a superidea, but D doesn't honor superideas, it's a practical language. Also memoization is a use case for varying access between different methods of the same class. Would you address that too?
'encapsulation' is an abstract concept. It may well be overrated, but that doesn't mean it's not useful, and sometimes necessary. Without it, we humans would have a hard time understanding anything, about anything. It's an vital component of how we understand things. (yes, I have psych degree ;-) The old OOP ideals of "all member variables should be private" and "global variables should be avoided", have clearly not been the best choice, over time, and certainly should never apply by default, for all cases. What's important, is the designer(programmer, programming team) have the options to strategically use this principles to accomodate the design they believe is best for them. This is particulary important when doing OOP, which is very different to the C like procedural progammning you often find in the D community. That C like mentality, I believe, is the source of the module design in D (i.e. everything global to the module, and that's all there is too it). Fortunately, Swift (which intenationally set out to drop all the baggage that came with C and C like thinking), 'seems' (I've only been using it a couple of days), like a very nice alternative to D, for me - not just because it returns that choice to me, but the syntax is very pleasing to understand and work with (one of D's biggest advantages too). With the options available to me in Swift, I feel 100% comfortable in programming in the large. Not so in D. programming in the small ;-) But in the many years I've been 'playing' with D, I've never considered it a suitable language, for me, to program in the large - primarily because of the 'everything is global in the module, and we in D, don't want you to have any other choice in this'.. .thing.
Jun 16 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 07:45:52 UTC, Kagamin wrote:
 ..
 Also memoization is a use case for varying access between 
 different methods of the same class. Would you address that too?
I got no idea what that is all about. I just want to make a private variable in my class, private to the class ;-)
Jun 16 2022
parent reply Kagamin <spam here.lot> writes:
On Thursday, 16 June 2022 at 08:58:09 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 07:45:52 UTC, Kagamin wrote:
 ..
 Also memoization is a use case for varying access between 
 different methods of the same class. Would you address that 
 too?
I got no idea what that is all about. I just want to make a private variable in my class, private to the class ;-)
When you have a lazily initialized field, you need to use an accessor, because if you read the raw field, you get an uninitialized value and error as a result, so only the accessor should have access to the field.
Jun 16 2022
next sibling parent forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 11:10:33 UTC, Kagamin wrote:
 On Thursday, 16 June 2022 at 08:58:09 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 07:45:52 UTC, Kagamin wrote:
 ..
 Also memoization is a use case for varying access between 
 different methods of the same class. Would you address that 
 too?
I got no idea what that is all about. I just want to make a private variable in my class, private to the class ;-)
When you have a lazily initialized field, you need to use an accessor, because if you read the raw field, you get an uninitialized value and error as a result, so only the accessor should have access to the field.
as this is a little over my head, I think, I'll answer it this way. if you can memoize now in D, you can still memoize if this idea were implemented. I'm happy to be corrected here.
Jun 16 2022
prev sibling next sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Thursday, 16 June 2022 at 11:10:33 UTC, Kagamin wrote:

 When you have a lazily initialized field, you need to use an 
 accessor, because if you read the raw field, you get an 
 uninitialized value and error as a result, so only the accessor 
 should have access to the field.
You can do that already for static/global functions by placing the cache in the function scope. In D, you can't access a function's scope at all, so it is true encapsulation.
Jun 16 2022
prev sibling parent forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 11:10:33 UTC, Kagamin wrote:
 ...
 When you have a lazily initialized field, you need to use an 
 accessor, because if you read the raw field, you get an 
 uninitialized value and error as a result, so only the accessor 
 should have access to the field.
I think the answer here, is that if you can't access a lazily initialized field because you made it 'private(scope)', then don't make it 'private(scope)'. 'private(scope)' is not meant to replace anything. 'private(scope)' would just be a design constraint 'option' (an option that so many of us have had for decades), for you to use when you think it is appropriate for you to use. You explicately state your intent with it, and the compiler will know and enforce that intent (at compile time).
Jun 16 2022
prev sibling parent reply Olivier Pisano <olivier.pisano laposte.net> writes:
On Thursday, 16 June 2022 at 00:02:41 UTC, forkit wrote:
 So I found this discussion from 2003! That's (at least) how 
 long this has been going on.

 It will continue to go on of course, because there is no right 
 or wrong way here.
Yes, every once in a while we get such discussions when someone finds out that D doesn't work exactly like [insert one's favorite language here] and pretends that is THE cause of the lack of popularity of D. Or that we absolutely need a new syntax for an existing feature to match the new language du jour, like when Go introduced the := operator. We were told that we HAD to add it too, back then, to avoid typing 'auto'. If you really want to add a new visibility level to D, you'll have to write a DIP and convince the community that the existing four are not enough. Pretending that you'll be leaving for [whatever language better fits your needs] may only indicate that you don't care.
Jun 16 2022
next sibling parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 08:51:26 UTC, Olivier Pisano wrote:
 Yes, every once in a while we get such discussions when someone 
 finds out that D doesn't work exactly like [insert one's 
 favorite language here] and pretends that is THE cause of the 
 lack of popularity of D.
[insert one's favorite language here] like this you mean: [some of the most popular and widely used languages in the world]
Jun 16 2022
next sibling parent reply Olivier Pisano <olivier.pisano laposte.net> writes:
On Thursday, 16 June 2022 at 08:55:52 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 08:51:26 UTC, Olivier Pisano wrote:
 Yes, every once in a while we get such discussions when 
 someone finds out that D doesn't work exactly like [insert 
 one's favorite language here] and pretends that is THE cause 
 of the lack of popularity of D.
[insert one's favorite language here] like this you mean: [some of the most popular and widely used languages in the world]
Which doesn't mean it would fit in D and play well with other D features. Especially since everyone has different favorite.
Jun 16 2022
next sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Thursday, 16 June 2022 at 09:54:48 UTC, Olivier Pisano wrote:

 world]
Which doesn't mean it would fit in D and play well with other D features.
Module-private already doesn't play well with other D features ('invariant()', 'synchronized')
 Especially since everyone has different favorite.
Jun 16 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 09:58:27 UTC, Max Samukha wrote:
 On Thursday, 16 June 2022 at 09:54:48 UTC, Olivier Pisano wrote:

 world]
Which doesn't mean it would fit in D and play well with other D features.
Module-private already doesn't play well with other D features ('invariant()', 'synchronized')
In what way are they affected?
Jun 16 2022
parent reply Max Samukha <maxsamukha gmail.com> writes:
On Thursday, 16 June 2022 at 10:41:03 UTC, Ola Fosheim Grøstad 
wrote:

 Module-private already doesn't play well with other D features 
 ('invariant()', 'synchronized')
In what way are they affected?
They assume encapsulation is at the class level.
Jun 16 2022
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 12:27:43 UTC, Max Samukha wrote:
 On Thursday, 16 June 2022 at 10:41:03 UTC, Ola Fosheim Grøstad 
 wrote:

 Module-private already doesn't play well with other D 
 features ('invariant()', 'synchronized')
In what way are they affected?
They assume encapsulation is at the class level.
Yes, but they also assume full encapsulation "Smalltalk style".
Jun 16 2022
prev sibling next sibling parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 09:54:48 UTC, Olivier Pisano wrote:
 On Thursday, 16 June 2022 at 08:55:52 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 08:51:26 UTC, Olivier Pisano 
 wrote:
 Yes, every once in a while we get such discussions when 
 someone finds out that D doesn't work exactly like [insert 
 one's favorite language here] and pretends that is THE cause 
 of the lack of popularity of D.
[insert one's favorite language here] like this you mean: [some of the most popular and widely used languages in the world]
Which doesn't mean it would fit in D and play well with other D features. Especially since everyone has different favorite.
My point is, either it supports one of the most important aspects I've worked with in OOP over 20 years, or it doesn't. i.e. it doesn't. would be nice if it did - 'if' it could fit in the language and work well with other things. are you suggesting i want it in the language, no matter what the cost is?
Jun 16 2022
parent reply Olivier Pisano <olivier.pisano laposte.net> writes:
On Thursday, 16 June 2022 at 10:46:33 UTC, forkit wrote:
 My point is, either it supports one of the most important 
 aspects I've worked with in OOP over 20 years, or it doesn't.

 i.e. it doesn't.

 would be nice if it did - 'if' it could fit in the language and 
 work well with other things.

 are you suggesting i want it in the language, no matter what 
 the cost is?
I am suggesting that if I copied and pasted some random D feature in another language, it may not fit in that language, because the context is different. D has already some features that don't play along well together (immutability and OOP, for instance). I am suggesting that 'because some other language has it' is not a valid argument, whether or not that language is successful. I am suggesting language design is hard. I am suggesting you write a DIP, so you can come with an evaluation of this cost, since you are the one asking for it.
Jun 16 2022
next sibling parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 11:45:11 UTC, Olivier Pisano wrote:
 ..
 I am suggesting you write a DIP, so you can come with an 
 evaluation of this cost, since you are the one asking for it.
To be honest, any DIP that only has one name written on it, is a red flag to me. The point of discussing this first, is not replace the DIP process, but to enhance the quality of it, so it can be considered on merits, and not all the silly arguments that always arise when scope privacy is raised. So far, it seems like all the silly arguments have been exhausted ;-) But wow... it took a while.
Jun 16 2022
next sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Thursday, 16 June 2022 at 23:02:05 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 11:45:11 UTC, Olivier Pisano wrote:
 ..
 I am suggesting you write a DIP, so you can come with an 
 evaluation of this cost, since you are the one asking for it.
To be honest, any DIP that only has one name written on it, is a red flag to me.
common, just common. The DIP process is good. What would you think of a democracy where decisions are took every time someone gets angry. Doors open to lobbying. lobbying leads to completly incoherant communities that are actually shaped of sub-communities that barely tolerate themselves. Passed the elipse, what I mean is that "you cant always get what you want", just like in real life you have to accept that the way of living is an unperfect compromise between people. So is a programming language that's actually used IRL. The way to bring changes is not anger, it's called DIP.
Jun 16 2022
next sibling parent forkit <forkit gmail.com> writes:
On Friday, 17 June 2022 at 01:09:29 UTC, Basile B. wrote:
 ..
 The way to bring changes is not anger, it's called DIP.
yes I agree. btw. I cannot recall every gettng angry over this issue ;-) frustrated yes, angry no. In any case. I've made two decisions. (1) Not to proceed with this idea (2) To stop using D, completely. Reasons for (1) are that the vast majority of D users do not compose problems using OO like decomposition. So it is almost impossible to find like minded people willing to co-author a DIP like this. Also, since most D users do not do OO decomposition, it would be difficult to find support for the DIP once introduced. Also, Walter would certainly prevent it, regardless. Reasons for (2). This comes back to Walter waking up one morning and putting ImportC into the langauge at his own volition, and nobody really challenging that. That makes me nervous. It means anything could happen anytime in D, if Walter makes that decision. I felt really uncomfortable using D ever since I say the 'trivial' PR from Walter! I'm moving on. So you're welcome to let this thread die off. Alternatively, I'm sure Mike is eager to find a reason to lock it - now he has one ;-)
Jun 16 2022
prev sibling parent reply Paulo Pinto <pjmlp progtools.org> writes:
On Friday, 17 June 2022 at 01:09:29 UTC, Basile B. wrote:
 On Thursday, 16 June 2022 at 23:02:05 UTC, forkit wrote:
 [...]
common, just common. The DIP process is good. What would you think of a democracy where decisions are took every time someone gets angry. Doors open to lobbying. lobbying leads to completly incoherant communities that are actually shaped of sub-communities that barely tolerate themselves. Passed the elipse, what I mean is that "you cant always get what you want", just like in real life you have to accept that the way of living is an unperfect compromise between people. So is a programming language that's actually used IRL. The way to bring changes is not anger, it's called DIP.
Where is the DIP for ImportC or live?
Jun 16 2022
next sibling parent Tejas <notrealemail gmail.com> writes:
On Friday, 17 June 2022 at 06:18:30 UTC, Paulo Pinto wrote:
 On Friday, 17 June 2022 at 01:09:29 UTC, Basile B. wrote:
 On Thursday, 16 June 2022 at 23:02:05 UTC, forkit wrote:
 [...]
common, just common. The DIP process is good. What would you think of a democracy where decisions are took every time someone gets angry. Doors open to lobbying. lobbying leads to completly incoherant communities that are actually shaped of sub-communities that barely tolerate themselves. Passed the elipse, what I mean is that "you cant always get what you want", just like in real life you have to accept that the way of living is an unperfect compromise between people. So is a programming language that's actually used IRL. The way to bring changes is not anger, it's called DIP.
Where is the DIP for ImportC or live?
Atleast for ` live`, the closest thing to a formal document was DIP 1021, I believe https://github.com/dlang/DIPs/blob/793f83911fdc8c88c6ef34e6a36b5e11e3e574e5/DIPs/DIP1021.md
Jun 17 2022
prev sibling parent reply Dukc <ajieskola gmail.com> writes:
On Friday, 17 June 2022 at 06:18:30 UTC, Paulo Pinto wrote:
 Where is the DIP for ImportC
According to Walter in last DConf online ImportC is supposed to be compiler-specific thing, not part of the language. Of course this means it's description should not be in the spec. It belongs to the dmd manual.
 or  live?
[here,](https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md) well not quite but kind of. The attribute itself is not part of that DIP but at least it describes an important part of ` live`. But I get your point, that the language maintainers have not always gone through the DIP process when adding new functionality. IMO it should not be a requirement for them to do so when there is no reason to, but it should be the standard procedure when designing something major. I share your viewpoint that Walter has sometimes cowboyed past the process (or tried to) when it'd been better to write a DIP or at least discuss the issue before acting. His track record is not all bad though. The bottom type DIP Walter submitted was rejected, but a revision of that by Dennis was later accepted.
Jun 17 2022
parent Paulo Pinto <pjmlp progtools.org> writes:
On Friday, 17 June 2022 at 11:10:39 UTC, Dukc wrote:
 On Friday, 17 June 2022 at 06:18:30 UTC, Paulo Pinto wrote:
 Where is the DIP for ImportC
According to Walter in last DConf online ImportC is supposed to be compiler-specific thing, not part of the language. Of course this means it's description should not be in the spec. It belongs to the dmd manual.
 or  live?
[here,](https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md) well not quite but kind of. The attribute itself is not part of that DIP but at least it describes an important part of ` live`. But I get your point, that the language maintainers have not always gone through the DIP process when adding new functionality. IMO it should not be a requirement for them to do so when there is no reason to, but it should be the standard procedure when designing something major. I share your viewpoint that Walter has sometimes cowboyed past the process (or tried to) when it'd been better to write a DIP or at least discuss the issue before acting. His track record is not all bad though. The bottom type DIP Walter submitted was rejected, but a revision of that by Dennis was later accepted.
In other language communities, compiler changes are also driven by DIPs like processes. Anyway, you got my point.
Jun 18 2022
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Thursday, 16 June 2022 at 23:02:05 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 11:45:11 UTC, Olivier Pisano wrote:
 ..
 I am suggesting you write a DIP, so you can come with an 
 evaluation of this cost, since you are the one asking for it.
To be honest, any DIP that only has one name written on it, is a red flag to me. The point of discussing this first, is not replace the DIP process, but to enhance the quality of it, so it can be considered on merits, and not all the silly arguments that always arise when scope privacy is raised.
The point of the DIP process is to enhance the proposal. Almost every DIP starts as a result of forum discussions. All the discussion you've done so far, for example, surely has provided enough material for an initial draft. When you're drafting the DIP, you can come to the forums, give a link to the draft in your DIP repository fork, and discuss the topic further refine your arguments, take suggestions, etc. Once you submit the draft, the DIP is in Draft Review while it's in the PR queue. People can come in and leave comments, and you can discuss and debate the proposal to improve it. The Community Review round(s) then serve to further refine it. The Final Review is one last chance to look for major flaws, then it's sent off to Walter and Atila for assessment. Multiple people contribute to every DIP, no matter how many people actually have their name in the author field.
Jun 16 2022
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/16/2022 4:45 AM, Olivier Pisano wrote:
 I am suggesting language design is hard.
Not the least of which is there is no such thing as a correct language design. There are only tradeoffs.
Jun 17 2022
parent reply Max Samukha <maxsamukha gmail.com> writes:
On Friday, 17 June 2022 at 21:40:58 UTC, Walter Bright wrote:
 On 6/16/2022 4:45 AM, Olivier Pisano wrote:
 I am suggesting language design is hard.
Not the least of which is there is no such thing as a correct language design. There are only tradeoffs.
There is an inconsistent language design. If the main paradigm the language is built around is class-based OOP, then it is reasonable to expect that 'private' is class-private (or at least there is a way to express class-private).
Jun 17 2022
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/17/2022 10:14 PM, Max Samukha wrote:
 On Friday, 17 June 2022 at 21:40:58 UTC, Walter Bright wrote:
 Not the least of which is there is no such thing as a correct language design. 
 There are only tradeoffs.
There is an inconsistent language design. If the main paradigm the language is built around is class-based OOP, then it is reasonable to expect that 'private' is class-private (or at least there is a way to express class-private).
Consistency is a worthy goal, but as I explained in my recent Code Europe presentation, too much consistency leads to undesirable results, too. For example: for (int i = 0; i; ++i); { ... } D adds grammatical inconsistency to reject that. And then there's that famously inconsistent symbol table lookup that D does that everyone but me insisted is intuitive :-)
Jun 17 2022
next sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Saturday, 18 June 2022 at 05:50:56 UTC, Walter Bright wrote:
 On 6/17/2022 10:14 PM, Max Samukha wrote:
 On Friday, 17 June 2022 at 21:40:58 UTC, Walter Bright wrote:
 Not the least of which is there is no such thing as a correct 
 language design. There are only tradeoffs.
There is an inconsistent language design. If the main paradigm the language is built around is class-based OOP, then it is reasonable to expect that 'private' is class-private (or at least there is a way to express class-private).
Consistency is a worthy goal, but as I explained in my recent Code Europe presentation, too much consistency leads to undesirable results, too. For example: for (int i = 0; i; ++i); { ... } D adds grammatical inconsistency to reject that.
Yes, that's a good one. I still believe it wasn't worth the special case. Such special cases tend to cause other issues, which are often disregarded (like highly annoying hindrances to generic programming).
 And then there's that famously inconsistent symbol table lookup 
 that D does that everyone but me insisted is intuitive :-)
You might have based your decisions on the feedback by the vociferous few while there is the silent majority whose opinion is unknown. I've been familiar with D since around 2006 and never voiced my opinion about the module-level private until now.
Jun 18 2022
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Saturday, 18 June 2022 at 09:42:40 UTC, Max Samukha wrote:
 Yes, that's a good one. I still believe it wasn't worth the 
 special case.
What special case? Using `;` as an empty statement instead of `{}` is not allowed anywhere in D as far as I can tell.
Jun 18 2022
next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 18 June 2022 at 15:01:16 UTC, Dennis wrote:
 On Saturday, 18 June 2022 at 09:42:40 UTC, Max Samukha wrote:
 Yes, that's a good one. I still believe it wasn't worth the 
 special case.
What special case? Using `;` as an empty statement instead of `{}` is not allowed anywhere in D as far as I can tell.
No conflicts... **Scope Example:** ```d void main() { import std.stdio; { enum ver = 1; // (!) } enum ver = 208; // (!) double d = ver; while (d++ <= ver) { "Hello!".write(" D Compiler v"); } { d /= 100; double subVer = 0.1; // (?) d.writeln(subVer); } double subVer = 0.9; // what? writeln(d + subVer); // next deneration D3 } /* Prints: Hello! D Compiler v2.10.1 3 */ ```
Jun 18 2022
parent Dennis <dkorpel gmail.com> writes:
On Saturday, 18 June 2022 at 15:58:45 UTC, Salih Dincer wrote:
 No conflicts...

 **Scope Example:**
I don't follow, what is the example demonstrating?
Jun 18 2022
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/18/2022 8:01 AM, Dennis wrote:
 On Saturday, 18 June 2022 at 09:42:40 UTC, Max Samukha wrote:
 Yes, that's a good one. I still believe it wasn't worth the special case.
What special case? Using `;` as an empty statement instead of `{}` is not allowed anywhere in D as far as I can tell.
It's not allowed as an empty statement.
Jun 18 2022
prev sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Saturday, 18 June 2022 at 15:01:16 UTC, Dennis wrote:
 On Saturday, 18 June 2022 at 09:42:40 UTC, Max Samukha wrote:
 Yes, that's a good one. I still believe it wasn't worth the 
 special case.
What special case? Using `;` as an empty statement instead of `{}` is not allowed anywhere in D as far as I can tell.
The empty statement is a special case. No special cases would be allowing any statement.
Jun 18 2022
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/18/2022 2:42 AM, Max Samukha wrote:
 You might have based your decisions on the feedback by the vociferous few
while 
 there is the silent majority whose opinion is unknown. I've been familiar with
D 
 since around 2006 and never voiced my opinion about the module-level private 
 until now.
Not even Andrei agreed with me. Not a single person that I recall. Anytime one interfaces with humans, inconsistency turns out to be desirable. Here's another inconsistency: void func() { int a; { int a; // error } }
Jun 18 2022
next sibling parent Ola Fosheim Gr <ola.fosheim.grostad gmail.com> writes:
On Saturday, 18 June 2022 at 21:17:52 UTC, Walter Bright wrote:
 Anytime one interfaces with humans, inconsistency turns out to 
 be desirable.
No. Common mistakes is a linter/warning issue or a syntax redesign issue.
 Here's another inconsistency:

   void func()
   {
       int a;
       {
          int a;  // error
       }
    }
More likely to be annoying as useful, now you need to refactor if you add a mixin or if you copy code. Not being able to shadow variablenames such as «tmp» or «i» is just annoying.
Jun 18 2022
prev sibling next sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Saturday, 18 June 2022 at 21:17:52 UTC, Walter Bright wrote:

 Not even Andrei agreed with me. Not a single person that I 
 recall.

 Anytime one interfaces with humans, inconsistency turns out to 
 be desirable.

 Here's another inconsistency:

   void func()
   {
       int a;
       {
          int a;  // error
       }
    }
It seems we are talking about different kinds of inconsistency. I am talking about logical inconsistencies (contradictions) in the rules, e.g. 'invariant/synchronized' imply class-level encapsulation while the encapsulation is enforced with 'private', which is module-level. The special shadowing rules do not seem to introduce any logical inconsistencies. Also, there is already one human in this thread who is claiming they are annoying.))
Jun 19 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 19 June 2022 at 07:07:07 UTC, Max Samukha wrote:
 The special shadowing rules do not seem to introduce any 
 logical inconsistencies.
It is inconsistent with scoping semantics: classes within classes, structs within structs, and you are allowed to shadow globals. Yet shadowing when subclassing is allowed? It is just a personal style guideline that is forced on everybody for no particular reason, it is not a common mistake to make if you know what you are doing.
Jun 19 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 19 June 2022 at 07:41:37 UTC, Ola Fosheim Grøstad 
wrote:
 On Sunday, 19 June 2022 at 07:07:07 UTC, Max Samukha wrote:
 The special shadowing rules do not seem to introduce any 
 logical inconsistencies.
It is inconsistent with scoping semantics: classes within classes, structs within structs, and you are allowed to shadow globals. Yet shadowing when subclassing is allowed? It is just a personal style guideline that is forced on everybody for no particular reason, it is not a common mistake to make if you know what you are doing.
This is also legal, if you care about shadowing then this is a much more likely problem: ```D class A { int x; void increment(){ // lots of code int x; // lots of code x++; } } ``` So that scoping restriction is completely arbitrary. I believe Rust allows rebinding the name within the same scope, which might be unreasonable, but there is one advantage: you get to use a consistent naming scheme which makes code easier to read.
Jun 19 2022
parent reply Max Samukha <maxsamukha gmail.com> writes:
On Sunday, 19 June 2022 at 08:10:28 UTC, Ola Fosheim Grøstad 
wrote:

 ```

 So that scoping restriction is completely arbitrary.
I agree that it is arbitrary.
 I believe Rust allows rebinding the name within the same scope, 
 which might be unreasonable, but there is one advantage: you 
 get to use a consistent naming scheme which makes code easier 
 to read.
Rust in general is a great counterevidence to Walter's belief that a programming language should care about human interface. Programmers are only half-human anyway.
Jun 19 2022
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 19 June 2022 at 09:40:09 UTC, Max Samukha wrote:
 Rust in general is a great counterevidence to Walter's belief 
 that a programming language should care about human interface. 
 Programmers are only half-human anyway.
Heh, I don't know what Rust is evidence of, but the first thing you learn if you take a course on design of Humcan-Computer-Interfaces is that consistency is important.
Jun 19 2022
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/19/2022 2:40 AM, Max Samukha wrote:
 Rust in general is a great counterevidence to Walter's belief that a
programming 
 language should care about human interface.
Rust has the best language marketers I've ever seen.
Jun 20 2022
prev sibling parent forkit <forkit gmail.com> writes:
On Saturday, 18 June 2022 at 21:17:52 UTC, Walter Bright wrote:
 On 6/18/2022 2:42 AM, Max Samukha wrote:
 You might have based your decisions on the feedback by the 
 vociferous few while there is the silent majority whose 
 opinion is unknown. I've been familiar with D since around 
 2006 and never voiced my opinion about the module-level 
 private until now.
Not even Andrei agreed with me. Not a single person that I recall. ....
Can I interpret that as meaning, Andrei did not agree with the idea of the D module making class variables and members global to the module? Is that what you meant? Is this still his opinion?
Jun 19 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Saturday, 18 June 2022 at 05:50:56 UTC, Walter Bright wrote:
 Consistency is a worthy goal, but as I explained in my recent 
 Code Europe presentation, too much consistency leads to 
 undesirable results, too.

 For example:

     for (int i = 0; i; ++i);
     {
         ...
     }

 D adds grammatical inconsistency to reject that.

 And then there's that famously inconsistent symbol table lookup 
 that D does that everyone but me insisted is intuitive :-)
I'm not sure consistency with C, is necessarily a worthy goal. Of course you've demonstrated that in your for loop example (i.e. a good reason for D to not be consistent here). I can easily understand your reason for wanting to be inconsistent here. I've made this mistake numerouse times myself, as I'm sure many others have. What I cannot understand, is your refusal to allow a class to declare something private to the class. I'm not aware of programmers making mistakes because they declared something in a class to be private. If the made a mistake, it's a design mistake, not a mistake of being able to declare something private to a class. What is the rationale for this inconsistency in D? The only explanation I've ever seen from you, on this issue, is that "in D, the module is the unit of encapsualtion". But that is not a rationale for being inconsistent here. What is the rationale?
Jun 19 2022
parent reply Sergey <kornburn yandex.ru> writes:
On Sunday, 19 June 2022 at 08:12:28 UTC, forkit wrote:
 On Saturday, 18 June 2022 at 05:50:56 UTC, Walter Bright wrote:

 What is the rationale?
Just leave it here, to be sure, that every participant of the thread have seen this: https://dlang.org/blog/2018/11/06/lost-in-translation-encapsulation/
Jun 19 2022
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 19 June 2022 at 09:46:40 UTC, Sergey wrote:
 On Sunday, 19 June 2022 at 08:12:28 UTC, forkit wrote:
 On Saturday, 18 June 2022 at 05:50:56 UTC, Walter Bright wrote:

 What is the rationale?
Just leave it here, to be sure, that every participant of the thread have seen this: https://dlang.org/blog/2018/11/06/lost-in-translation-encapsulation/
It just took the viewpoint that "people are accustomed to other languages", but there was no rationale for D being different to other statically typed class based languages. It offered no explanation for why it is a good idea to deviate from the norm.
Jun 19 2022
prev sibling next sibling parent reply forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 09:46:40 UTC, Sergey wrote:
 On Sunday, 19 June 2022 at 08:12:28 UTC, forkit wrote:
 On Saturday, 18 June 2022 at 05:50:56 UTC, Walter Bright wrote:

 What is the rationale?
Just leave it here, to be sure, that every participant of the thread have seen this: https://dlang.org/blog/2018/11/06/lost-in-translation-encapsulation/
So am aware of this article, of course. It explains why 'everything is global' in a module - in essence, to be able to encapsulate classes and 'free' functions in the one place, and thereby avoid the need to have C++ like 'friend'. Fine. I don't reject that argument. What I reject (and what the article does not address), is not having an 'option' to 'unfriend'. What is the rationale for that? Not having that option, means you cannot restrict access to an object through the set of operations as specified by that type. That means, you've lost the essential capacity for using the class as a means of data abstraction. In D, the class is not a data abstraction anymore. It's just one 'thing' in the larger module abstraction. As I've said before, in D, you cannot put "wtf" into an int. The int is a data abstraction with defined invariants that the compiler will enforce. I just wanted an option, so that my class type could have its invariants explicately declared, and enforced by the compiler, and not have to worry, that someday, someone, maybe even me, might end up putting "wtf" into my int.
Jun 19 2022
parent forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 10:11:10 UTC, forkit wrote:

I wonder if D should have shown even more inconsistency here, and 
instead of calling the class a 'class', called it 

Jun 19 2022
prev sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Sunday, 19 June 2022 at 09:46:40 UTC, Sergey wrote:
 On Sunday, 19 June 2022 at 08:12:28 UTC, forkit wrote:
 On Saturday, 18 June 2022 at 05:50:56 UTC, Walter Bright wrote:

 What is the rationale?
Just leave it here, to be sure, that every participant of the thread have seen this: https://dlang.org/blog/2018/11/06/lost-in-translation-encapsulation/
And the nonsensical debates like https://dlang.org/blog/2018/11/06/lost-in-translation-encapsu ation/#comment-6546 wouldn't have happened, if D had done the most reasonable thing from the start - make 'private' mean 'private to the current scope'; provide 'private(ancestor)' for choosing the encapsulation boundary; and maybe provide shortcuts for module and package. That's it. No need for articles trying to justify the arbitrary imposition.
Jun 19 2022
parent reply forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 11:19:43 UTC, Max Samukha wrote:
 ...
 And the nonsensical debates like 
 https://dlang.org/blog/2018/11/06/lost-in-translation-encapsu
ation/#comment-6546 wouldn't have happened, if D had done the most reasonable
thing from the start - make 'private' mean 'private to the current scope';
provide 'private(ancestor)' for choosing the encapsulation boundary; and maybe
provide shortcuts for module and package. That's it. No need for articles
trying to justify the arbitrary imposition.
Additionally, in the comments of that article, Jim Balter uses the Ceylon Language in his argument against the idea of allowing scope level privacy within a module. But looking at the Ceylon Language docs, I see they already made the argument for me ;-) "Of course, we could have chosen to make shared visibility the default, providing a private annotation to restrict access. But that would have been very harmful to modularity, a key goal of the language. The "best" default is the most restrictive option. Otherwise, the developer of a module might accidently make something shared that they don't intend to make shared, and be forced to either continue to support the unintentionally-shared operation for the rest of the life of the module, or break clients. There would be nothing the compiler could do to warn you when you accidently left off a private annotation." https://ceylon-lang.org/documentation/1.2/faq/language-design/
Jun 19 2022
parent reply forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 22:45:44 UTC, forkit wrote:

I'm happy (more than happy actually) to conclude my input into 
this discusssion with this:

D has, by design, rendereed meaningless the concept of a private 
class member (by not even allowing you to declare one as being 
private!).

So, what happens when you do this?

Well, Stroustrup provided some insight into the problem this 
would likely cause.. a looooonnngggg..... time ago...:

(NOTE: below he discusses this in the context of inheritance, not 
modules):

"A member of a derived class has no special permission to access 
private members of its base class ..
This comes as a surprise to some, but consider the alternative: 
that a member function of a derived class could access the 
private members of its base class. The concept of a private 
member would be rendered meaningless by allowing a programmer to 
gain access to the private part of a class simply by deriving a 
new class from it. Furthermore, one could no longer find all uses 
of a private name by looking at the functions declared as members 
and friends of that class. One would have to examine every source 
file of the complete program for derived classes, then examine 
every function of those classes, then find every class derived 
from those classes, etc. This is, at best, tedious and often 
impractical." - Section 12.2.1 - The C++ Programming Language, 
3rd Ed. Stroustrup 1997.

In relation to D, the problem is this:

D does not use friend declarations. In essence, everything 
declared in the module is a friend of any class declared within 
that module.

In D, you have no say in this (i.e. it provides no language 
mechanism to decalre a private member of a class.)

So not only has D rendered meaningless the concept of a private 
class member, it's also makes it impossible to know the friends 
of a class by looking at the
class definition, for its friends.

In essence, you must examine **all** code within a module 
**manually** before you can understand anything about the class.

The class type in D, has been (intentionally!!) morphed into a 



back into a kinda class type, by putting it in its own module.

Then can be no justification for this. It simply must be fixed, 
before one can take D seriously, as being a language where you 
can do OOP.

The class type is not a type that should be open to this abuse.
Jun 20 2022
parent reply surlymoor <surlymoor cock.li> writes:
On Monday, 20 June 2022 at 08:25:34 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 22:45:44 UTC, forkit wrote:
[...]
I'm happy (more than happy actually) to conclude my input into this discusssion with this: [...]
Then draft a DIP to get the ball rolling. But you won't.
Jun 20 2022
next sibling parent forkit <forkit gmail.com> writes:
On Monday, 20 June 2022 at 09:01:09 UTC, surlymoor wrote:
 On Monday, 20 June 2022 at 08:25:34 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 22:45:44 UTC, forkit wrote:
[...]
I'm happy (more than happy actually) to conclude my input into this discusssion with this: [...]
Then draft a DIP to get the ball rolling. But you won't.
It has more chance of happening in D3.. but even, it's only a slight chance. A DIP is pointless. The problem is: - there's just not enough OO programmers in the D community to get sufficient support for the idea. That gets clearly demonstrated whenever the idea emerges (again .. and again). - most D programmers seems to be using procedural decomposition, not OO decomposition. - Walter has voiced his opinion on this matter. I cannot see how a DIP would change his perspective. - Who would implement it? Walter? I mean c'mon.. My guess is, that those insisting that a DIP be produced, are likely those that know such a DIP will never be accepted. Then they can put this idea to rest, forever - cause the DIP was rejected. Lastly, I have available, really good alternatives to D, for OOP. So I think my attention is better spend elsewhere now. If D3 ever arrives on the scene, I'll take a brief look to see if anything has changed. But I doubt it will.
Jun 20 2022
prev sibling parent reply bauss <jj_1337 live.dk> writes:
On Monday, 20 June 2022 at 09:01:09 UTC, surlymoor wrote:
 On Monday, 20 June 2022 at 08:25:34 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 22:45:44 UTC, forkit wrote:
[...]
I'm happy (more than happy actually) to conclude my input into this discusssion with this: [...]
Then draft a DIP to get the ball rolling. But you won't.
Why waste hours writing a DIP when there's a better chance of winning the lottery than to have this accepted as a DIP. I think it's okay to express your dislikes and what you wished D could do better, without necessarily putting in the work yourself for the change; especially when it is something as divided as this. I don't think it would pass, the same way that the default we have now wouldn't pass a DIP either. It's just a too dividend topic and I don't think either side of the coin is inherently wrong, it just depends on your usage of D etc. tends to favor this change, where the opposite is true for people coming from C, C++ etc. I do however also think that enough is enough, clearly the dislike has been expressed enough and at some point you just gotta stop complaining. But I also believe that "writing a DIP" isn't always an acceptable response, even if that's what's needed to make the change. Before one writes a DIP you need a) make sure there is sufficient support for the implementation b) make sure the topic has a chance of passing "class private" only passes a) but not b)
Jun 20 2022
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 20/06/2022 9:30 PM, bauss wrote:
 It's just a too dividend topic and I don't think either side of the coin 
 is inherently wrong, it just depends on your usage of D and what your 

 this change, where the opposite is true for people coming from C, C++ etc.
 
 I do however also think that enough is enough, clearly the dislike has 
 been expressed enough and at some point you just gotta stop complaining.
Most people don't care about it as a feature. There was very little dislike being expressed in this thread, mostly indifference. It would pass if for no other reason than to stop this topic coming up in the future. So yes, there is very much a point to do a DIP, especially when Mike has offered to give it preferential treatment!
Jun 20 2022
parent reply forkit <forkit gmail.com> writes:
On Monday, 20 June 2022 at 09:43:42 UTC, rikki cattermole wrote:
 On 20/06/2022 9:30 PM, bauss wrote:
 It's just a too dividend topic and I don't think either side 
 of the coin is inherently wrong, it just depends on your usage 
 of D and what your background is, I think people coming from 

 is true for people coming from C, C++ etc.
 
 I do however also think that enough is enough, clearly the 
 dislike has been expressed enough and at some point you just 
 gotta stop complaining.
Most people don't care about it as a feature. There was very little dislike being expressed in this thread, mostly indifference. It would pass if for no other reason than to stop this topic coming up in the future. So yes, there is very much a point to do a DIP, especially when Mike has offered to give it preferential treatment!
no. It should only ever pass, on the basis, that it enhances software engineering. the language and compiler is essentially just an app, and should serve the needs of those using it, not those designing it. to the extent it does just that, for 'most' D users, fine. it doesn't for me though. Private members have ALWAYS been a vital component in my software engineering processes, and it will remain so. what I've always found puzzling, is that so many in the D community are against this. I don't mean in favour of the status quo (private to the module), but being **so against** just the 'option' - which they would always retain the right to use, or not, according to what they think enhances (or doesn't) their software engineering process. There are numerous explanations I can come up with for this. Any or all could well be true. Also, the discussion has mostly not been about complaining, as someone suggested, but having to respond to the D community's complete and utter dislike of this idea - that's where all the effort goes really. I think D3 should maybe get rid of the class type completely, and stop trying to pretend it supports OOP. Then there will no longer ever be any confusion, discussion, complaining...... ever again.
Jun 20 2022
parent forkit <forkit gmail.com> writes:
On Monday, 20 June 2022 at 23:36:43 UTC, forkit wrote:

look, even typescript have shown this courtesy to OO programmers:

https://www.typescriptlang.org/docs/handbook/classes.html
Jun 20 2022
prev sibling parent surlymoor <surlymoor cock.li> writes:
On Monday, 20 June 2022 at 09:30:18 UTC, bauss wrote:
 On Monday, 20 June 2022 at 09:01:09 UTC, surlymoor wrote:
 On Monday, 20 June 2022 at 08:25:34 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 22:45:44 UTC, forkit wrote:
[...]
I'm happy (more than happy actually) to conclude my input into this discusssion with this: [...]
Then draft a DIP to get the ball rolling. But you won't.
Why waste hours writing a DIP when there's a better chance of winning the lottery than to have this accepted as a DIP. I think it's okay to express your dislikes and what you wished D could do better, without necessarily putting in the work yourself for the change; especially when it is something as divided as this.
I'd be hypocrite to disagree, but the topic at hand, as you've noted, has been exhausted. And yet, the main complainant seems to still have plenty of energy. Thus, why not put that towards something more substantive instead continually serving stale bread?
Jun 20 2022
prev sibling next sibling parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Saturday, 18 June 2022 at 05:14:20 UTC, Max Samukha wrote:
 On Friday, 17 June 2022 at 21:40:58 UTC, Walter Bright wrote:
 On 6/16/2022 4:45 AM, Olivier Pisano wrote:
 I am suggesting language design is hard.
Not the least of which is there is no such thing as a correct language design. There are only tradeoffs.
There is an inconsistent language design. If the main paradigm the language is built around is class-based OOP, then it is reasonable to expect that 'private' is class-private (or at least there is a way to express class-private).
D is not built around a class-based OOP paradigm. D includes class OOP as one paradigm among many.
Jun 18 2022
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 18 June 2022 at 07:46:27 UTC, FeepingCreature wrote:
 D is not built around a class-based OOP paradigm. D includes 
 class OOP as one paradigm
It is breaks with the conventions for «class private». Most, if not all, class-based languages have OOP as a feature and not a paradigm. The inventors stressed that OOP was not a paradigm.
Jun 18 2022
parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Saturday, 18 June 2022 at 07:53:52 UTC, Ola Fosheim Grøstad 
wrote:
 On Saturday, 18 June 2022 at 07:46:27 UTC, FeepingCreature 
 wrote:
 D is not built around a class-based OOP paradigm. D includes 
 class OOP as one paradigm
It is breaks with the conventions for «class private». Most, if not all, class-based languages have OOP as a feature and not a paradigm. The inventors stressed that OOP was not a paradigm.
I mean, I think it's important in this case because aiui `private` is ignored in modules because modules are the more central unit of abstraction than classes; a function in a module is "on the same level" as a method in the class. So in that specific sense, it's more correct to call D a module-based language than a class-based one. Aside: that's actually important if you consider that certain features do not work with class methods!
Jun 18 2022
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 18 June 2022 at 08:04:55 UTC, FeepingCreature wrote:
 I mean, I think it's important in this case because aiui 
 `private` is ignored in modules because modules are the more 
 central unit of abstraction than classes; a function in a 
 module is "on the same level" as a method in the class. So in 
 that specific sense, it's more correct to call D a module-based 
 language than a class-based one.
I guess I understand what you mean, you can technically use a module as a singleton, but I would claim that modules primarily are namespaces. But it is a fact that it is *very unusual* to provide many access control mechanisms, but not class-private. Even Python, that provides no access control, does at least do name mangling for class private fields. So being surprised about this is warranted. (Not suggesting this is a pressing issue for D, as things like getting better memory management is much more important.)
Jun 18 2022
prev sibling next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Saturday, 18 June 2022 at 08:04:55 UTC, FeepingCreature wrote:
 I mean, I think it's important in this case because aiui 
 `private` is ignored in modules because modules are the more 
 central unit of abstraction than classes; a function in a 
 module is "on the same level" as a method in the class. So in 
 that specific sense, it's more correct to call D a module-based 
 language than a class-based one.
More importantly, modules are the unit of abstraction over implementation. When I open a module, I see all the code that implement everything that's in the module. If there is something in there that I shouldn't see, then it shouldn't be in the module. It's very simple really.
Jun 18 2022
parent reply forkit <forkit gmail.com> writes:
On Saturday, 18 June 2022 at 17:38:21 UTC, deadalnix wrote:
 More importantly, modules are the unit of abstraction over 
 implementation. When I open a module, I see all the code that 
 implement everything that's in the module. If there is 
 something in there that I shouldn't see, then it shouldn't be 
 in the module.

 It's very simple really.
Modules are an ideal form of encapsulation for procedural like programming. D makes for a nice language for procedural like progamming. The problem is, D claims to support OOP, using classes -> "The object-oriented features of D all come from classes." - https://dlang.org/spec/class.html However, when you put this claim to the test, you suddenly find there is no language mechanism to apply one of the most important principles in OOP, which is information hiding -> of course I mean this in the context of code within a module. The idea that all data within a class is global to the module, and therefore mutable, by default, is inconsistent with the claim that D makes. Worse even, there is no language option to change this, let alone enforce it (at compile time). Information hiding is central to the concept of a concrete type, which in OOP, is what a class is -> a concrete type. OK. So how do you apply the principle of information hiding in D. Well, you put the class that needs this, into it's own module. Sure, you've now you've got a defacto means of hiding information (since there's no other code in the module) - but that comes at the cost of new design constraint that gets imposed on you (one class per module, always, just as a defacto means to make it into a concrete type). But this is not OOP. Lets be really clear about this. Therefore I find the claim, that D support OOP, to be.. dubious. D clearly wants to be a procedural programming language, not an OOP. I have no problem with that. All power to ya... But please, don't make the claim that the language supports OOP, when it clearly is missing a language feature to allow a class to be a concrete type. In OOP, private should be the default in classes, and it is usually the better choice (paraphrasing Stroustrup here). This is why I only feel comfortable doing OOP in other languages, and not D. The lack of a language feature to keep information private to the class (and enforce that design intention at compile time) , cannot be justified as just being a tradeoff. Rather, it was a design decision, made by Walter. It was a decision made for convenience, but at the expense of OOP. Other languages that do support OOP, have not 'needed' to make this 'tradeoff' in order to get a cohesive language that can support OOP.
Jun 18 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Sunday, 19 June 2022 at 00:48:12 UTC, forkit wrote:
 Information hiding is central to the concept of a concrete 
 type, which in OOP, is what a class is -> a concrete type.

 OK. So how do you apply the principle of information hiding in 
 D. Well, you put the class that needs this, into it's own 
 module.

 Sure, you've now you've got a defacto means of hiding 
 information (since there's no other code in the module) - but 
 that comes at the cost of new design constraint that gets 
 imposed on you (one class per module, always, just as a defacto 
 means to make it into a concrete type).

 But this is not OOP. Lets be really clear about this.
It's funny that you say this, because this is exactly how information hiding works in the Common Lisp Object System:
 Like the OO systems in most dynamic languages, CLOS does not 
 enforce
 encapsulation. Any slot can be accessed using the slot-value
 function or via (optionally auto-generated) accessor methods. To
 access it via slot-value you have to know the name of the slot. 
 CL
 programmers use the language's package facility to declare which
 functions or data structures are intended for export.
Source: https://en.wikipedia.org/wiki/Common_Lisp_Object_System A "package" in Common Lisp is more or less the same thing as a module in D: a namespace for symbol definitions. If you are willing to bite the bullet here and say that CLOS is "not OOP" because it lacks encapsulation, then fair enough, but at that point I think you must admit that your idea of what counts as OOP is not shared by most developers (including Alan Kay himself, who cited Lisp as an example of OOP done right).
Jun 18 2022
next sibling parent forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 02:39:52 UTC, Paul Backus wrote:
 ..
 It's funny that you say this, because this is exactly how 
 information hiding works in the Common Lisp Object System:
 ...

 Source: https://en.wikipedia.org/wiki/Common_Lisp_Object_System

 A "package" in Common Lisp is more or less the same thing as a 
 module in D: a namespace for symbol definitions.

 If you are willing to bite the bullet here and say that CLOS is 
 "not OOP" because it lacks encapsulation, then fair enough, but 
 at that point I think you must admit that your idea of what 
 counts as OOP is not shared by most developers (including Alan 
 Kay himself, who cited Lisp as an example of OOP done right).
Well sure. The earth rotates around the sun. If someone tells me the sun rotates around the earth, thent I can say that is factually incorrect. There are no 'facts' when it comes to describing what OOP is ;-) Anyone is free to make anything up, to suit what they think it is, or should be. But to me, an object is a self-contained encapsulated unit of abstraction. By that I mean is has control of its own state and behaviour. For this to be possible, it needs to be able to 'hide' stuff from the outside world (to ensure the outside world is not changing its state or behaviour willy nilly.. ) It escapes my comprehension, as to why D cannot provide compiler support for this design, whereas other major langauges do. Was D targetting CLOS programmers? Was it targetting C++ programmers, but insisting the change their way of thinking if they come over to D? Seems like such a simple, useful feature, to be able to say "this is private to this class, so compiler, please enforce this at compile time in case anyone else tries to change me without my permission". I've been able to do exactly this, for 20+ years! And C++ has provided this to its users for considerably longer. Even Swift, a relatively new language, can do this - no problem whatsoever. I'd like to know what the so called 'tradeoff' is, for not having this 'option', cause is sure seems a tradeoff to help the compiler writer, and not the programmer.
Jun 18 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 02:39:52 UTC, Paul Backus wrote:
 ...
 If you are willing to bite the bullet here and say that CLOS is 
 "not OOP" because it lacks encapsulation, then fair enough, but 
 at that point I think you must admit that your idea of what 
 counts as OOP is not shared by most developers (including Alan 
 Kay himself, who cited Lisp as an example of OOP done right).
I know nothing of CLOS. A quick read of CLOS wiki, and it seems you can turn a ceramic aardvark into a graceful Old World ruminant, at runtime! That doesn't sound like my understanding of the open/closed principle, which is what most of us (I guess) would associate with OOP. i.e. "Software entities (classes, modules, functions, etc.) Should be open for extension, but closed for modification."
Jun 18 2022
next sibling parent reply Paulo Pinto <pjmlp progtools.org> writes:
On Sunday, 19 June 2022 at 06:22:57 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 02:39:52 UTC, Paul Backus wrote:
 ...
 If you are willing to bite the bullet here and say that CLOS 
 is "not OOP" because it lacks encapsulation, then fair enough, 
 but at that point I think you must admit that your idea of 
 what counts as OOP is not shared by most developers (including 
 Alan Kay himself, who cited Lisp as an example of OOP done 
 right).
I know nothing of CLOS. A quick read of CLOS wiki, and it seems you can turn a ceramic aardvark into a graceful Old World ruminant, at runtime! That doesn't sound like my understanding of the open/closed principle, which is what most of us (I guess) would associate with OOP. i.e. "Software entities (classes, modules, functions, etc.) Should be open for extension, but closed for modification."
I advise getting a copy of The Art of MetaObject Protocol, a CS OOP literature gem that describes the genesis of CLOS. https://en.m.wikipedia.org/wiki/The_Art_of_the_Metaobject_Protocol Additionally a look into LOOP, the Xerox PARC Interlisp-D based OOP, used on their Lisp Machines variant. https://www.softwarepreservation.org/projects/LISP/interlisp-d Or speaking of them, the Flavors system, https://en.m.wikipedia.org/wiki/Flavors_(programming_language) As I already mentioned on the other thread, CS literature is full of various understandings of what is OOP all about.
Jun 18 2022
parent reply forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 06:46:17 UTC, Paulo Pinto wrote:
 
 ..
 As I already mentioned on the other thread, CS literature is 
 full of various understandings of what is OOP all about.
so is 20+ years of doing it ;-)
Jun 19 2022
parent reply forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 07:01:38 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 06:46:17 UTC, Paulo Pinto wrote:
 
 ..
 As I already mentioned on the other thread, CS literature is 
 full of various understandings of what is OOP all about.
so is 20+ years of doing it ;-)
also, by view of OOP, is that any principles you apply to it, confirm with principles in the real world. e.g. you cannot turn a cat into a mouse. although having said that, they're both made of molecules, that are made of atoms. so you can turn atoms, into molecules, and molecules into a cat, or a mouse. but as long as the cat is a cat, it's a cat, not a mouse.
Jun 19 2022
parent reply Paulo Pinto <pjmlp progtools.org> writes:
On Sunday, 19 June 2022 at 07:06:21 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 07:01:38 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 06:46:17 UTC, Paulo Pinto wrote:
 
 ..
 As I already mentioned on the other thread, CS literature is 
 full of various understandings of what is OOP all about.
so is 20+ years of doing it ;-)
also, by view of OOP, is that any principles you apply to it, confirm with principles in the real world. e.g. you cannot turn a cat into a mouse. although having said that, they're both made of molecules, that are made of atoms. so you can turn atoms, into molecules, and molecules into a cat, or a mouse. but as long as the cat is a cat, it's a cat, not a mouse.
Last time I checked, Common Lisp, JavaScript and ML derived languages like Objective Caml are still real world, used at places like Google and Facebook. But I digress...
Jun 19 2022
parent forkit <forkit gmail.com> writes:
On Sunday, 19 June 2022 at 08:13:54 UTC, Paulo Pinto wrote:
 On Sunday, 19 June 2022 at 07:06:21 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 07:01:38 UTC, forkit wrote:
 On Sunday, 19 June 2022 at 06:46:17 UTC, Paulo Pinto wrote:
 
 ..
 As I already mentioned on the other thread, CS literature is 
 full of various understandings of what is OOP all about.
so is 20+ years of doing it ;-)
also, by view of OOP, is that any principles you apply to it, confirm with principles in the real world. e.g. you cannot turn a cat into a mouse. although having said that, they're both made of molecules, that are made of atoms. so you can turn atoms, into molecules, and molecules into a cat, or a mouse. but as long as the cat is a cat, it's a cat, not a mouse.
Last time I checked, Common Lisp, JavaScript and ML derived languages like Objective Caml are still real world, used at places like Google and Facebook. But I digress...
well, in the real world, a cat 'could' turn into mouse. but only once all the molecules have dissipated (from death). but whether those atoms will from new molecules, that create a mouse, nobody knows. therefore, I cannot see why CLOS allows you to turn a cat into a mouse. I can only surmise, that CLOS programmers like playing god ;-) "playing god" != "OOP" .. but i digress too ...
Jun 19 2022
prev sibling parent reply zjh <fqbqrr 163.com> writes:
On Sunday, 19 June 2022 at 06:22:57 UTC, forkit wrote:

 "Software entities (classes, modules, functions, etc.) Should 
 be open for extension, but closed for modification."
This is the problem of D. when it is very obvious ,then they must oppose it. Finally, they say that they are experts which should break the (rules or)consistency! We are the `first`! Therefore, D's community is small .
Jun 18 2022
parent zjh <fqbqrr 163.com> writes:
On Sunday, 19 June 2022 at 06:49:30 UTC, zjh wrote:

 We are the `first`!
We all know that D likes to rebel against `authority`. The problem is that sometimes authority is right! For example, `encapsulation and consistency` are the `principles` of design language! A question of `principle`! They don't care!
Jun 19 2022
prev sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Saturday, 18 June 2022 at 08:04:55 UTC, FeepingCreature wrote:

 a function in a module is "on the same level" as a method in 
 the class.
If it is on the same level, then I would expect 'foo' below to lock the mutex and run the invariant check: ```d synchronized class C { private int x; private int y = 1; invariant() { assert(y == x + 1); } } void foo(C c, int x) { c.x = x; c.y = x + 1; } ```
Jun 18 2022
next sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Saturday, 18 June 2022 at 18:02:08 UTC, Max Samukha wrote:

 void foo(C c, int x)
should be `shared(C)`
Jun 18 2022
prev sibling next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Saturday, 18 June 2022 at 18:02:08 UTC, Max Samukha wrote:
 On Saturday, 18 June 2022 at 08:04:55 UTC, FeepingCreature 
 wrote:

 a function in a module is "on the same level" as a method in 
 the class.
If it is on the same level, then I would expect 'foo' below to lock the mutex and run the invariant check: ```d synchronized class C { private int x; private int y = 1; invariant() { assert(y == x + 1); } } void foo(C c, int x) { c.x = x; c.y = x + 1; } ```
If the argument is that synchronized and invariant are messed up, yes.
Jun 18 2022
parent Max Samukha <maxsamukha gmail.com> writes:
On Saturday, 18 June 2022 at 21:13:07 UTC, deadalnix wrote:
 On Saturday, 18 June 2022 at 18:02:08 UTC, Max Samukha wrote:
 On Saturday, 18 June 2022 at 08:04:55 UTC, FeepingCreature 
 wrote:

 a function in a module is "on the same level" as a method in 
 the class.
If it is on the same level, then I would expect 'foo' below to lock the mutex and run the invariant check: ```d synchronized class C { private int x; private int y = 1; invariant() { assert(y == x + 1); } } void foo(C c, int x) { c.x = x; c.y = x + 1; } ```
If the argument is that synchronized and invariant are messed up, yes.
The argument is that those imply that encapsulation is on the class level while 'private' used to enforce the encapsulation is on the module level, which makes the design inconsistent. If people argue that there is no "correct" level of encapsulation (which I agree with), then 'synchronized/invariant' should align with that view.
Jun 18 2022
prev sibling parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Saturday, 18 June 2022 at 18:02:08 UTC, Max Samukha wrote:
 On Saturday, 18 June 2022 at 08:04:55 UTC, FeepingCreature 
 wrote:

 a function in a module is "on the same level" as a method in 
 the class.
If it is on the same level, then I would expect 'foo' below to lock the mutex and run the invariant check: ```d synchronized class C { private int x; private int y = 1; invariant() { assert(y == x + 1); } } void foo(C c, int x) { c.x = x; c.y = x + 1; } ```
And on reflection, I think I agree that it should.
Jun 20 2022
parent Mike Parker <aldacron gmail.com> writes:
On Monday, 20 June 2022 at 09:27:59 UTC, FeepingCreature wrote:
 On Saturday, 18 June 2022 at 18:02:08 UTC, Max Samukha wrote:
 On Saturday, 18 June 2022 at 08:04:55 UTC, FeepingCreature 
 wrote:

 a function in a module is "on the same level" as a method in 
 the class.
If it is on the same level, then I would expect 'foo' below to lock the mutex and run the invariant check: ```d synchronized class C { private int x; private int y = 1; invariant() { assert(y == x + 1); } } void foo(C c, int x) { c.x = x; c.y = x + 1; } ```
And on reflection, I think I agree that it should.
Me, too. This is an aspect I hadn't considered before. It's given me an idea.
Jun 20 2022
prev sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Saturday, 18 June 2022 at 07:46:27 UTC, FeepingCreature wrote:

 D is not built around a class-based OOP paradigm. D includes 
 class OOP as one paradigm among many.
I think 'main' still applies to D1.
Jun 18 2022
prev sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 18 June 2022 at 05:14:20 UTC, Max Samukha wrote:
 On Friday, 17 June 2022 at 21:40:58 UTC, Walter Bright wrote:
 On 6/16/2022 4:45 AM, Olivier Pisano wrote:
 I am suggesting language design is hard.
Not the least of which is there is no such thing as a correct language design. There are only tradeoffs.
There is an inconsistent language design.
Is there for D; do you mean D! I think D Programming Language is consistent. Even from Walter's example I see no problem? ```d void main() { for (int i = 1; i; --i) { //assert(i != 1); // error in loop block } // Equivalent: size_t singleLoopError = 1; do { assert(singleLoopError != 1); } while (--singleLoopError); } ``` SDB 79
Jun 18 2022
parent Nick Treleaven <nick geany.org> writes:
On Saturday, 18 June 2022 at 08:49:30 UTC, Salih Dincer wrote:
   for (int i = 1; i; --i)
   {
D supports this or the `for (i = 0; i; i++)` variant. Walter's example has a semicolon before the brace - that is an error as it's easy not to notice it!
Jun 18 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 09:54:48 UTC, Olivier Pisano wrote:
 Which doesn't mean it would fit in D and play well with other D 
 features.

 Especially since everyone has different favorite.
fair enough. eveyone has there favoutite language, and their favourite style, and their favourite this.. and that... this feature request (discussion) is not about a 'favourite' anything. this is about a core principle in OOP. all of us ask the question 'does this need to be exposed to others'. well, I sure hope that's a question on your mind, when your programming. if it's not, you should not be programming. In OOP we ask this question all the time. More than most other paradigms, I'd suggest. I think the people complaing about this, either don't get this, or they're anti OOP (and don't tell me they don't exist in the D community ;-) ... The only real question on peoples mind, should be -> if we allow a class to have private members (to the class), how will this fit in and affect the rest of the language (technically). at this stage, not a single person has bothered to even make an attempt to explore an answer to this question.
Jun 16 2022
next sibling parent forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 11:26:23 UTC, forkit wrote:
 at this stage, not a single person has bothered to even make an 
 attempt to explore an answer to this question.
except maybe Kagamin ;-)
Jun 16 2022
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 11:26:23 UTC, forkit wrote:
 The only real question on peoples mind, should be ->  if we 
 allow a class to have private members (to the class), how will 
 this fit in and affect the rest of the language (technically).

 at this stage, not a single person has bothered to even make an 
 attempt to explore an answer to this question.
I think I have, but I can do it again: Since D has meta programming capabilities it can affect meta programming code that makes assumptions about access control modes being fixed to the existing set. As such it will be a breaking change, but will probably not break most programs. (Basically all changes that go beyond syntax sugar are breaking changes in D.)
Jun 16 2022
parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 11:31:48 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 16 June 2022 at 11:26:23 UTC, forkit wrote:
 The only real question on peoples mind, should be ->  if we 
 allow a class to have private members (to the class), how will 
 this fit in and affect the rest of the language (technically).

 at this stage, not a single person has bothered to even make 
 an attempt to explore an answer to this question.
I think I have, but I can do it again: Since D has meta programming capabilities it can affect meta programming code that makes assumptions about access control modes being fixed to the existing set. As such it will be a breaking change, but will probably not break most programs. (Basically all changes that go beyond syntax sugar are breaking changes in D.)
ok, except you too ;-) I must have missed this in all the nonsense going on... the constraint is optional, just as using meta programming is optional. but if the D language requires that 'meta programming in D must be able to access class members that are private to the scope of the class', then assuming this would not be the case if the suggestion were implemented, then we have a first, genuine, issue to consider ;-)
Jun 16 2022
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 11:40:16 UTC, forkit wrote:
 the constraint is optional, just as using meta programming is 
 optional.
It isn't optional if you write libraries that other people depend on. If someone gives your library a type, then you need to deal with that type.
Jun 16 2022
parent reply forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 11:48:08 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 16 June 2022 at 11:40:16 UTC, forkit wrote:
 the constraint is optional, just as using meta programming is 
 optional.
It isn't optional if you write libraries that other people depend on. If someone gives your library a type, then you need to deal with that type.
well I've never written a library that others depends on to do metaprogramming ;-) what I'm saying, is if you do, the design constraint is optional. I cannot answer the question as to whether allowing a class to have members that are private to the class, would have a negative impact on metaprogramming in D. If someone is saying that it will, then .. can they please explain how and why that would be, so we can all understand?
Jun 16 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 12:02:17 UTC, forkit wrote:
 I cannot answer the question as to whether allowing a class to 
 have members that are private to the class, would have a 
 negative impact on metaprogramming in D.

 If someone is saying that it will, then .. can they please 
 explain how and why that would be, so we can all understand?
If you can detect it, then it is a breaking change in the context of meta-programming. It is up to you to prove in your DIP that it cannot be detected if you claim that it is a non-breaking change.
Jun 16 2022
parent reply Chris Katko <ckatko gmail.com> writes:
On Thursday, 16 June 2022 at 12:08:27 UTC, Ola Fosheim Grøstad 
wrote:
 If you can detect it, then it is a breaking change in the 
 context of meta-programming.
Isn't that like saying: adding a uint128 type breaks the language. Because you can detect it?
Jun 16 2022
next sibling parent reply bauss <jj_1337 live.dk> writes:
On Thursday, 16 June 2022 at 13:02:11 UTC, Chris Katko wrote:
 On Thursday, 16 June 2022 at 12:08:27 UTC, Ola Fosheim Grøstad 
 wrote:
 If you can detect it, then it is a breaking change in the 
 context of meta-programming.
Isn't that like saying: adding a uint128 type breaks the language. Because you can detect it?
It is and I think it's far from a solid argument against anything. If your meta programming depends on something as trivial as those and will break with any minor changes like that then your code is probably wrong to begin with.
Jun 16 2022
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 13:15:52 UTC, bauss wrote:
 On Thursday, 16 June 2022 at 13:02:11 UTC, Chris Katko wrote:
 On Thursday, 16 June 2022 at 12:08:27 UTC, Ola Fosheim Grøstad 
 wrote:
 If you can detect it, then it is a breaking change in the 
 context of meta-programming.
Isn't that like saying: adding a uint128 type breaks the language. Because you can detect it?
It is and I think it's far from a solid argument against anything.
Actually, on second thoughts, it would not be a breaking change as it is listed in the language spec: https://dlang.org/spec/type.html I guess one could say that the compilers are not compliant, unless I missed a footnote somewhere. Basically, whether it is a breaking change or not, depends on the wording of the language spec (if you have one). If it says that you should not assume this or that, then it is not a breaking change even if people do assume this or that (because the code they wrote was outside the spec and could be considered undefined behaviour).
Jun 16 2022
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 13:02:11 UTC, Chris Katko wrote:
 Isn't that like saying: adding a uint128 type breaks the 
 language. Because you can detect it?
Depends on whether the language provides a "mandated" mechanism in the standard library for dealing with arbitrary bit widths. Since *cent* has been known as a potential 128bit type, you probably should try to write generic code over integers using generic mechanisms where available. But yes, most extensions at the language level can break things. It is less problematic to do it as extensions of the standard library with optimizations (that ends up using 128 bit instructions). The result would be the same, just non-breaking.
Jun 16 2022
prev sibling parent reply The Zealot <zod zod.zod> writes:
On Thursday, 16 June 2022 at 11:40:16 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 11:31:48 UTC, Ola Fosheim Grøstad 
 wrote:
 On Thursday, 16 June 2022 at 11:26:23 UTC, forkit wrote:
 [...]
I think I have, but I can do it again: Since D has meta programming capabilities it can affect meta programming code that makes assumptions about access control modes being fixed to the existing set. As such it will be a breaking change, but will probably not break most programs. (Basically all changes that go beyond syntax sugar are breaking changes in D.)
ok, except you too ;-) I must have missed this in all the nonsense going on... the constraint is optional, just as using meta programming is optional. but if the D language requires that 'meta programming in D must be able to access class members that are private to the scope of the class', then assuming this would not be the case if the suggestion were implemented, then we have a first, genuine, issue to consider ;-)
you are always fast to dismiss any potential problems. Write a DIP. Add all possible ways in which adding _class private_ will affect/break existing code. for starters: __traits(getVisibility), .tupleof, std.traits.hasMember, std.traits.hasStaticMember
Jun 21 2022
next sibling parent bauss <jj_1337 live.dk> writes:
On Tuesday, 21 June 2022 at 11:05:10 UTC, The Zealot wrote:
 you are always fast to dismiss any potential problems. Write a 
 DIP. Add all possible ways in which adding _class private_ will 
 affect/break existing code.
 for starters: __traits(getVisibility), .tupleof, 
 std.traits.hasMember, std.traits.hasStaticMember
They're already broken today without class private. Or at least .tupleof and hasMember is. Depending on how it's added then it won't add any breakage to those as existing code will still yield the same results, it will only be for new code where there'll be a difference and arguably neither of those should return any class private members. It should work just as it do today in theory. The only difference will be in future apis exposed. Example where nothing changes: Today: ``` class Foo { int x; int y; } // exposed: x,y ``` If class private existed: ``` class Foo { int x; int y; hidden int z; } // exposed: x,y ``` Example where something changes: Today: ``` class Foo { int x; int y; int z; } // exposed: x,y,z ``` If class private existed: ``` class Foo { int x; int y; hidden int z; } // exposed: x,y // breaking change in this case only // clearly you would mark this as a breaking change in the new release // that is not a problem for libraries and/or user code - it's only a problem for ex. phobos // arguably phobos would just never change anything to class private ```
Jun 21 2022
prev sibling next sibling parent reply forkit <forkit gmail.com> writes:
On Tuesday, 21 June 2022 at 11:05:10 UTC, The Zealot wrote:
 you are always fast to dismiss any potential problems. Write a 
 DIP. Add all possible ways in which adding _class private_ will 
 affect/break existing code.
 for starters: __traits(getVisibility), .tupleof, 
 std.traits.hasMember, std.traits.hasStaticMember
Well, I'd argue the opposite - i.e. that too many in the D community are always fast to dismiss any potential problems. 'this is how we do it in D, so there!' 'our language doesn't need to give you that option. instead, we'd rather force you into putting every class into its own module.'. The vast majority of programmers have a different concept of the class, to what D is wanting to **impose** on them. Can you even see the problem here? The problem is certainly NOT a result of wanting 'an option' to make a member private within the specification of a class. You may retort.. I know you will ;-) // ---- module test; safe: class Base { private int x = 100; } class Derived : Base {} void main() { import std.stdio : writeln; Derived d = new Derived(); writeln(d.x); // this is so sad. } // ----
Jun 21 2022
parent reply The Zealot <zod zod.zod> writes:
On Tuesday, 21 June 2022 at 23:36:06 UTC, forkit wrote:
 On Tuesday, 21 June 2022 at 11:05:10 UTC, The Zealot wrote:
 you are always fast to dismiss any potential problems. Write a 
 DIP. Add all possible ways in which adding _class private_ 
 will affect/break existing code.
 for starters: __traits(getVisibility), .tupleof, 
 std.traits.hasMember, std.traits.hasStaticMember
Well, I'd argue the opposite - i.e. that too many in the D community are always fast to dismiss any potential problems. 'this is how we do it in D, so there!' 'our language doesn't need to give you that option. instead, we'd rather force you into putting every class into its own module.'. The vast majority of programmers have a different concept of the class, to what D is wanting to **impose** on them. Can you even see the problem here? The problem is certainly NOT a result of wanting 'an option' to make a member private within the specification of a class. You may retort.. I know you will ;-) // ---- module test; safe: class Base { private int x = 100; } class Derived : Base {} void main() { import std.stdio : writeln; Derived d = new Derived(); writeln(d.x); // this is so sad. } // ----
``` module test; import std.stdio; safe: interface IDerived { void fine() safe; } IDerived createDerived() { static class Base { private int x = 100; } static class Derived : Base, IDerived { void fine() safe{writeln(x);} } return new Derived(); } void main() { import std.stdio : writeln; auto d = createDerived(); d.fine(); writeln(d.x); // look, no access. } ```
Jun 23 2022
parent forkit <forkit gmail.com> writes:
On Thursday, 23 June 2022 at 10:55:17 UTC, The Zealot wrote:
 ```
 module test;
 import std.stdio;

  safe:
 interface IDerived {
     void fine()  safe;
 }

 IDerived createDerived() {
     static class Base { private int x = 100;  }
     static class Derived : Base, IDerived { void 
 fine() safe{writeln(x);} }
     return new Derived();
 }

 void main()
 {
     import std.stdio : writeln;

     auto d = createDerived();
     d.fine();
     writeln(d.x); // look, no access.
 }
 ```
That is certainly interesting ;-) However, it looks like a lot of work, just to limit access to a class member :-( I was rethinking how I could 're-frame' my argument, in light of that 'Civility' thread. Perhaps like this: i.e. what is the value of having keyword 'const' in this code below? I mean, if you want the string to remain constant, then don't change it. Why bother using 'const'? Let's just get rid of const. It's kinda pointless, since you're the programmer, writing the code. The answer is simple. The compiler can statically **guarantee** the correctness of your program. You do not even have to worry about making a mistake, and accidently modifying it. Imagine if 'my programming language', said to you, we don't have the keyword 'const'. If you want it const, then don't change it. Or, put the function in its own module, so that it can't be changed. So I do not see the difference, between the benefit of having const, and the benefit of having private(this). Both provide static verification of your program. There is no downside to that, IMO. Obtaining static verification makes for a worthwhile addition to the language, IMO. It's not just some fad I want to bring into D, cause other languages have it. I'm not sure this re-framing of my argument will help, but, this is my last hoorahhh on this topic ;-) // --- module test; safe: import std; void main() { printString("Hello World!"); } void printString(const string str) { writeln(str); } // ----
Jun 25 2022
prev sibling parent forkit <forkit gmail.com> writes:
On Tuesday, 21 June 2022 at 11:05:10 UTC, The Zealot wrote:

and btw:


"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." - 
Walter Bright

https://forum.dlang.org/post/pr110b$9j5$1 digitalmars.com

Oh great. He does get it afterall.

But what if you want closely interrelated classes that 
encapsulate a concept, in the same module, but don't want every 
class to have complete access to every part of every other 
class......

Oh. I know, just put each class in it's own module.
Jun 21 2022
prev sibling parent reply Kagamin <spam here.lot> writes:
On Thursday, 16 June 2022 at 08:55:52 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 08:51:26 UTC, Olivier Pisano wrote:
 Yes, every once in a while we get such discussions when 
 someone finds out that D doesn't work exactly like [insert 
 one's favorite language here] and pretends that is THE cause 
 of the lack of popularity of D.
[insert one's favorite language here] like this you mean: [some of the most popular and widely used languages in the world]
The D design is from Java, a popular and widely used language.
Jun 16 2022
next sibling parent forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 11:36:15 UTC, Kagamin wrote:
 The D design is from Java, a popular and widely used language.
well, i don't know from where the idea popped into Walters head actually came from... but pretty sure the module concept came well before Java arrived on the scene ;-)
Jun 16 2022
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 16 June 2022 at 11:36:15 UTC, Kagamin wrote:
 On Thursday, 16 June 2022 at 08:55:52 UTC, forkit wrote:
 On Thursday, 16 June 2022 at 08:51:26 UTC, Olivier Pisano 
 wrote:
 Yes, every once in a while we get such discussions when 
 someone finds out that D doesn't work exactly like [insert 
 one's favorite language here] and pretends that is THE cause 
 of the lack of popularity of D.
[insert one's favorite language here] like this you mean: [some of the most popular and widely used languages in the world]
The D design is from Java, a popular and widely used language.
From https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html : Modifier | Class | Package | Subclass | World :---------|:------------:| :-----: | :--------: | :---------: public |Y |Y |Y |Y |Y protected |Y |Y |Y |N no modifier |Y |Y |N |N private |Y |N |N |N So not the same as Java…
Jun 16 2022
prev sibling next sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Thursday, 16 June 2022 at 08:51:26 UTC, Olivier Pisano wrote:
 If you really want to add a new visibility level to D, you'll 
 have to write a DIP and convince the community that the 
 existing four are not enough.
Exactly. Maybe someone thought that the new attrib would be added just by complaining on the forums ? This topic comes so often that I'm surprised no one has written that DIP yet. I volonteer but be warned I'll propose to introduce "super private".
Jun 16 2022
parent reply bauss <jj_1337 live.dk> writes:
On Thursday, 16 June 2022 at 09:01:56 UTC, Basile B. wrote:
 I volonteer but be warned I'll propose to introduce "super 
 private".
No that is ambiguous because it sounds like it's private to the super class. It absolutely cannot use the super keyword.
Jun 16 2022
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Thursday, 16 June 2022 at 09:04:25 UTC, bauss wrote:
 On Thursday, 16 June 2022 at 09:01:56 UTC, Basile B. wrote:
 I volonteer but be warned I'll propose to introduce "super 
 private".
No that is ambiguous because it sounds like it's private to the super class. It absolutely cannot use the super keyword.
allright, I give up then ;)
Jun 16 2022
prev sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Thursday, 16 June 2022 at 09:04:25 UTC, bauss wrote:
 On Thursday, 16 June 2022 at 09:01:56 UTC, Basile B. wrote:
 I volonteer but be warned I'll propose to introduce "super 
 private".
No that is ambiguous because it sounds like it's private to the super class. It absolutely cannot use the super keyword.
meh in this context "super" would mean "really really"
Jun 16 2022
parent Chris Katko <ckatko gmail.com> writes:
On Thursday, 16 June 2022 at 14:58:33 UTC, Basile B. wrote:
 On Thursday, 16 June 2022 at 09:04:25 UTC, bauss wrote:
 On Thursday, 16 June 2022 at 09:01:56 UTC, Basile B. wrote:
 I volonteer but be warned I'll propose to introduce "super 
 private".
No that is ambiguous because it sounds like it's private to the super class. It absolutely cannot use the super keyword.
meh in this context "super" would mean "really really"
extra private! megapint private! "classified" exclusive secret
Jun 16 2022
prev sibling parent forkit <forkit gmail.com> writes:
On Thursday, 16 June 2022 at 08:51:26 UTC, Olivier Pisano wrote:
 If you really want to add a new visibility level to D, you'll 
 have to write a DIP and convince the community that the 
 existing four are not enough. Pretending that you'll be leaving 
 for [whatever language better fits your needs] may only 
 indicate that you don't care.
I aware that 'actual' change can only occur with DIP ;-) Unless of course you're Walter, in which case, you can just wake up one morning and put ImportC into the langauge..... and the whole D community now has to deal with that, like it or not. Walter will refuse it regardless. Even if he's forced to accept it, cause the community demands it, which compiler person in D do you think is going to have to implement it? Walter of course - and he'll make sure it's high on his agenda, no doubt. He has also around him, people that seem to think as he does. That never turns out well.
Jun 16 2022
prev sibling parent Tejas <notrealemail gmail.com> writes:
On Wednesday, 15 June 2022 at 07:40:37 UTC, forkit wrote:
 On Wednesday, 15 June 2022 at 06:26:51 UTC, Ola Fosheim Grøstad 
 wrote:
 [...]
btw. what is this SDC thing? Is it a D compiler? Does it inherit all the problems of the current compiler, or is it 'more modular', like the approach LLVM have taken, so that more people can work on it? I'm doubt that another monolithic compiler, will solve very much at all. They just quickly reach a point where they're too complex, and nobody dares touch it.
It's a completely new frontend for D It aims to solve the tooling issues for D development, while also being a full fledged compiler in it's own right https://youtu.be/AhR4PSExnqk
Jun 15 2022
prev sibling parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 15 June 2022 at 01:57:28 UTC, zjh wrote:
 On Wednesday, 15 June 2022 at 01:21:51 UTC, monkyyy wrote:

 Id suggest fixing ancient template bugs and getting several 
 competing compilers going to compete with c++;
In any case, we should not be afraid of `change`! not be afraid of `complexity`! Take a look at `'rust'`. It is becoming more and more `complex`. Take a look at `other mainstream languages`. Which is not `complex`? `C++23, c++26` is absolutely monsters! But people don't care!
If theres several old bugs, that suggests that the language is already past its complexity budget. Like dual context, or calling nested templates, or my little favorite little bug, really suggests that foundation is quite unstable; I tolerate it because I dont exactly see good implementations of templates anywhere but maybe poeple like c++ because dispite being uglier syntax maybe you can find a compiler that works when you find a blocking bug
Jun 15 2022
parent zjh <fqbqrr 163.com> writes:
On Wednesday, 15 June 2022 at 17:13:45 UTC, monkyyy wrote:
 but maybe poeple like c++ because dispite being uglier syntax .
`C++` template syntax is not ugly ,Just get used to it.
Jun 15 2022