www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Sealed classes - would you want them in D?

reply Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
Hello,

I've recently thought of sealed classes (sealed as in Scala, not 

start this thread first though to gather some opinions on the 
topic.

For those who never coded Scala and don't know sealed classes: a 
sealed class is a class which can be only extended in the same 
source file.

     sealed class MyClass {}

Translating to D, a sealed class would could only be extended in 
the same module. Additionally I would suggest 
"sealed(some.package) MyClass {}" syntax for classes that could 
only be extended in the particular package.

In Scala an important value of sealed classes is that compiler 
knows that and can aid programmer in pattern matching by 
detecting the missed cases. However, there is another value I 
see: limiting the extension of classes.

Some time ago I was working on a simple CQRS library and created 
an Entity class, where I wanted only a few specific subtypes for 
it. The library is built over a few defined entity types and user 
is not able to create their own types (should extend the 
particular subtype instead). Sealing the Entity class could 
enable me to define the closed set of subtypes and prevent new 
direct subtype creation outside the library.

Combining sealed with final library developer can create a 
completely closed type hierarchy.

Any thoughts on that proposal?
May 10 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 11/05/2018 1:22 AM, Piotr Mitana wrote:
 Hello,
 
 I've recently thought of sealed classes (sealed as in Scala, not as in 

 thread first though to gather some opinions on the topic.
 
 For those who never coded Scala and don't know sealed classes: a sealed 
 class is a class which can be only extended in the same source file.
 
      sealed class MyClass {}
 
 Translating to D, a sealed class would could only be extended in the 
 same module. Additionally I would suggest "sealed(some.package) MyClass 
 {}" syntax for classes that could only be extended in the particular 
 package.
 
 In Scala an important value of sealed classes is that compiler knows 
 that and can aid programmer in pattern matching by detecting the missed 
 cases. However, there is another value I see: limiting the extension of 
 classes.
 
 Some time ago I was working on a simple CQRS library and created an 
 Entity class, where I wanted only a few specific subtypes for it. The 
 library is built over a few defined entity types and user is not able to 
 create their own types (should extend the particular subtype instead). 
 Sealing the Entity class could enable me to define the closed set of 
 subtypes and prevent new direct subtype creation outside the library.
 
 Combining sealed with final library developer can create a completely 
 closed type hierarchy.
 
 Any thoughts on that proposal?
Adding a keyword like sealed isn't desirable. I'm trying to find fault of the concept, but it definitely is tough. You basically want protected, but only for specific packages, otherwise final. protected(foo, final)
May 10 2018
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 10 May 2018 at 13:47:16 UTC, rikki cattermole wrote:
 [snip]

 Adding a keyword like sealed isn't desirable.

 I'm trying to find fault of the concept, but it definitely is 
 tough.

 You basically want protected, but only for specific packages, 
 otherwise final.

 protected(foo, final)
My read was that he wants an escape hatch on final so that he can extend the type in a module and not have to worry about people in other modules extending them. So if he has module foo; class A { } final class B : A { } in one module, he wants to be able to create a new final class C : B { } and keep class B as final so that no one else can extend it in another module.
May 10 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 11/05/2018 2:43 AM, jmh530 wrote:
 On Thursday, 10 May 2018 at 13:47:16 UTC, rikki cattermole wrote:
 [snip]

 Adding a keyword like sealed isn't desirable.

 I'm trying to find fault of the concept, but it definitely is tough.

 You basically want protected, but only for specific packages, 
 otherwise final.

 protected(foo, final)
My read was that he wants an escape hatch on final so that he can extend the type in a module and not have to worry about people in other modules extending them. So if he has module foo; class A { } final class B : A {    } in one module, he wants to be able to create a new final class C : B {    } and keep class B as final so that no one else can extend it in another module.
You're right, I just didn't put it well. My current thinking is something along the lines of: modifier ( !|opt IdentifierList ) modifier ( !|opt IdentifierList , modifier ) Not quite correct grammar, but close enough. So: final(!mypackage) would do what Piotr wants.
May 10 2018
parent Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
On Thursday, 10 May 2018 at 14:48:23 UTC, rikki cattermole wrote:
 module foo;
 
 class A { }
 
 final class B : A {    }
 
 in one module, he wants to be able to create a new
 
 final class C : B {    }
 
 and keep class B as final so that no one else can extend it in 
 another module.
Not entirely. Let's use code to explain. We have: module pack.foo; sealed class A {} class B : A {} // Legal final class C : A {} // Legal sealed(pack) class D {} class E : D {} =================== module pack.bar; class F : A {} // Illegal, A is sealed class B1 : B {} // Legal, B is not sealed - A is class C1 : C {} // Illegal of course, as C is final class D1 : D {} // OK, D is package-sealed class E1 : E {} // OK, E is neither sealed nor final =================== module anotherpack.baz; class G : A {} // Illegal, A is sealed class B2 : B {} // Legal, B is not sealed class C2 : C {} // Illegal, C is final class D2 : D {} // Illegal, D is package-sealed for pack class E2 : E {} // Legal, E is neither sealed nor final In general: sealed means a special case of neither private, protected nor final and it probably could not be achieved with a combination of these two. Sealed does not mean private, as access to the class is not restricted in any way. It is also not transitive - class extending a sealed class can be extended freely unless they are sealed as well or final. Given those classes: sealed class Pet {} class Cat : Pet {} class Dog : Pet {} we can implement a different types of Cats and Dogs - but creating a Ferret or Parrot is illegal. So it may be used to limit one level of inheritance, but retain the freedom to extend the few defined types. Making the base class private would not be OK, as we don't want to restrict the access to that class.
May 11 2018
prev sibling next sibling parent reply Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Thursday, 10 May 2018 at 13:22:20 UTC, Piotr Mitana wrote:
 Hello,

 I've recently thought of sealed classes (sealed as in Scala, 

 decided to start this thread first though to gather some 
 opinions on the topic.

 For those who never coded Scala and don't know sealed classes: 
 a sealed class is a class which can be only extended in the 
 same source file.

     sealed class MyClass {}

 Translating to D, a sealed class would could only be extended 
 in the same module. Additionally I would suggest 
 "sealed(some.package) MyClass {}" syntax for classes that could 
 only be extended in the particular package.

 In Scala an important value of sealed classes is that compiler 
 knows that and can aid programmer in pattern matching by 
 detecting the missed cases. However, there is another value I 
 see: limiting the extension of classes.
[...]
 Combining sealed with final library developer can create a 
 completely closed type hierarchy.

 Any thoughts on that proposal?
How about extending the behaviour of ‘private’, which means private except for this module, to ‘final’, which would then allow sub typing in the same module but not outside? It would not break any code. Are there downsides to such a change?
May 10 2018
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 11/05/2018 3:18 AM, Bastiaan Veelo wrote:
 On Thursday, 10 May 2018 at 13:22:20 UTC, Piotr Mitana wrote:
 Hello,

 I've recently thought of sealed classes (sealed as in Scala, not as in 

 thread first though to gather some opinions on the topic.

 For those who never coded Scala and don't know sealed classes: a 
 sealed class is a class which can be only extended in the same source 
 file.

     sealed class MyClass {}

 Translating to D, a sealed class would could only be extended in the 
 same module. Additionally I would suggest "sealed(some.package) 
 MyClass {}" syntax for classes that could only be extended in the 
 particular package.

 In Scala an important value of sealed classes is that compiler knows 
 that and can aid programmer in pattern matching by detecting the 
 missed cases. However, there is another value I see: limiting the 
 extension of classes.
[...]
 Combining sealed with final library developer can create a completely 
 closed type hierarchy.

 Any thoughts on that proposal?
How about extending the behaviour of ‘private’, which means private except for this module, to ‘final’, which would then allow sub typing in the same module but not outside? It would not break any code. Are there downsides to such a change?
You can already sub type with private. What you can't do is sub type with both private and final. It should remain this way. Let's not go changing semantics of already understood language features. Exceptions to rules are not ok, nor will they be approved.
May 10 2018
prev sibling parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Thursday, 10 May 2018 at 15:18:56 UTC, Bastiaan Veelo wrote:

 How about extending the behaviour of ‘private’, which means 
 private except for this module, to ‘final’, which would then 
 allow sub typing in the same module but not outside? It would 
 not break any code. Are there downsides to such a change?
This was exactly my thought. It fits right in there with Walter's reasoning, you already have access to the module's code so rather than make you jump through hoops to access, lift the restriction within the module. To rikki's complaint, it would have the same unfortunate side affect of people complaining that they can't control the source code within the module. It wouldn't be an exception to the rule though, it would follow the rule. (I guess it depends on what rule you look at)
May 10 2018
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, May 10, 2018 13:22:20 Piotr Mitana via Digitalmars-d wrote:
 Hello,

 I've recently thought of sealed classes (sealed as in Scala, not

 start this thread first though to gather some opinions on the
 topic.

 For those who never coded Scala and don't know sealed classes: a
 sealed class is a class which can be only extended in the same
 source file.

      sealed class MyClass {}

 Translating to D, a sealed class would could only be extended in
 the same module. Additionally I would suggest
 "sealed(some.package) MyClass {}" syntax for classes that could
 only be extended in the particular package.

 In Scala an important value of sealed classes is that compiler
 knows that and can aid programmer in pattern matching by
 detecting the missed cases. However, there is another value I
 see: limiting the extension of classes.

 Some time ago I was working on a simple CQRS library and created
 an Entity class, where I wanted only a few specific subtypes for
 it. The library is built over a few defined entity types and user
 is not able to create their own types (should extend the
 particular subtype instead). Sealing the Entity class could
 enable me to define the closed set of subtypes and prevent new
 direct subtype creation outside the library.

 Combining sealed with final library developer can create a
 completely closed type hierarchy.

 Any thoughts on that proposal?
I think that the main thing is that the use case has to be strong enough to merit complicating the language further by adding such a feature, and I really don't know if the use case is really all that strong. My gut reaction is that it's catering to a very specific and rare use case and as such would not be worth adding, but I don't know. Idiomatic D tends to use classes rarely, and I can't think of any situation where what you're describing would ever have been useful to me, but that doesn't necessarily mean that some people wouldn't find it really useful, and depending on how much value it adds in such situations, it might be worth adding. Ultimately though, I think that if you want to create a DIP for something like this, you're going to need some very strong use cases where this is solving a real problem and why the current situation is lacking. If it's a significant improvement in enough situations, then you'll probably be able to get a DIP accepted, but if it's just helping in some rare cases, I'd expect it to stand a low chance of acceptance. Nothing stands out to me about the idea as being fundamentally bad though. - Jonathan M Davis
May 10 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Thursday, 10 May 2018 at 21:26:12 UTC, Jonathan M Davis wrote:
 Idiomatic D tends to use classes rarely...
What is the basis for this assertion? On a separate issue, 'private' should mean private! (not kinda-private). Let's not make D classes even more of joke.
May 10 2018
parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Friday, 11 May 2018 at 03:11:48 UTC, KingJoffrey wrote:
 On Thursday, 10 May 2018 at 21:26:12 UTC, Jonathan M Davis 
 wrote:
 Idiomatic D tends to use classes rarely...
What is the basis for this assertion?
D tends to prefer structs with UFCS member functions rather than classes, because one rarely needs the reference semantics or inheritance. Also, classes are pretty inconvenient because they are hard to use without the GC.
 On a separate issue, 'private' should mean private! (not 
 kinda-private).

 Let's not make D classes even more of joke.
`private` is for outside the module. Within the module, private is not applied because D wanted to avoid C++'s `friend` functions.
May 10 2018
next sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 `private` is for outside the module. Within the module, private 
 is not applied because D wanted to avoid C++'s `friend` 
 functions.
'private' is "meant" to be part of the implementation of 'the class'. Whereas D makes it part of the implementation of 'the module' ( which is an even higher level of abstraction). This is an abomination! A class should have the capacity to protect its attributes/methods - even from the module.
May 10 2018
next sibling parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Friday, 11 May 2018 at 04:43:09 UTC, KingJoffrey wrote:
 On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 `private` is for outside the module. Within the module, 
 private is not applied because D wanted to avoid C++'s 
 `friend` functions.
'private' is "meant" to be part of the implementation of 'the class'. Whereas D makes it part of the implementation of 'the module' ( which is an even higher level of abstraction). This is an abomination! A class should have the capacity to protect its attributes/methods - even from the module.
Let's not start this discussion again https://forum.dlang.org/post/tksnoqntxtpgqbwslxni forum.dlang.org
May 10 2018
next sibling parent reply Apocalypto <apocalypto gmail.com> writes:
On Friday, 11 May 2018 at 05:10:08 UTC, Uknown wrote:
 On Friday, 11 May 2018 at 04:43:09 UTC, KingJoffrey wrote:
 On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 Whereas D makes it part of the implementation of 'the module' 
 ( which is an even higher level of abstraction).

 This is an abomination!

 A class should have the capacity to protect its 
 attributes/methods - even from the module.
Let's not start this discussion again https://forum.dlang.org/post/tksnoqntxtpgqbwslxni forum.dlang.org
If an encapsulation problem is highlighted again and again, may be it's time to acknowledge at least that there is a problem.
May 10 2018
parent reply bauss <jj_1337 live.dk> writes:
On Friday, 11 May 2018 at 05:26:36 UTC, Apocalypto wrote:
 On Friday, 11 May 2018 at 05:10:08 UTC, Uknown wrote:
 On Friday, 11 May 2018 at 04:43:09 UTC, KingJoffrey wrote:
 On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 Whereas D makes it part of the implementation of 'the module' 
 ( which is an even higher level of abstraction).

 This is an abomination!

 A class should have the capacity to protect its 
 attributes/methods - even from the module.
Let's not start this discussion again https://forum.dlang.org/post/tksnoqntxtpgqbwslxni forum.dlang.org
If an encapsulation problem is highlighted again and again, may be it's time to acknowledge at least that there is a problem.
It's a problem to you, but not to me and I'm sure many others in the D community can agree that private being module level has a lot of benefits over private being "class-level".
May 11 2018
parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Friday, 11 May 2018 at 19:30:51 UTC, bauss wrote:
 It's a problem to you, but not to me and I'm sure many others 
 in the D community can agree that private being module level 
 has a lot of benefits over private being "class-level".
These are the benefit I can see: - it encourages more complex, ill-structured problem solving skills. - it increases cognitive load on those seeking to understand the solution (cause now they have to take into accont the 'entire' module, as opposed to smaller encapsulated units of code within the module.) We're back in goto land!
May 11 2018
prev sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Friday, 11 May 2018 at 05:10:08 UTC, Uknown wrote:
 On Friday, 11 May 2018 at 04:43:09 UTC, KingJoffrey wrote:
 On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 `private` is for outside the module. Within the module, 
 private is not applied because D wanted to avoid C++'s 
 `friend` functions.
'private' is "meant" to be part of the implementation of 'the class'. Whereas D makes it part of the implementation of 'the module' ( which is an even higher level of abstraction). This is an abomination! A class should have the capacity to protect its attributes/methods - even from the module.
Let's not start this discussion again https://forum.dlang.org/post/tksnoqntxtpgqbwslxni forum.dlang.org
My point is, that adding sealed or anything else to classes, is a waste of time, cause a class is D, is not really a class at all. A class in D, is some unprinciple pseudo-class, that cannot truly encapsulate itself any longer.
May 10 2018
prev sibling parent reply Dukc <ajieskola gmail.com> writes:
On Friday, 11 May 2018 at 04:43:09 UTC, KingJoffrey wrote:
 On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 `private` is for outside the module. Within the module, 
 private is not applied because D wanted to avoid C++'s 
 `friend` functions.
'private' is "meant" to be part of the implementation of 'the class'. Whereas D makes it part of the implementation of 'the module' ( which is an even higher level of abstraction). This is an abomination! A class should have the capacity to protect its attributes/methods - even from the module.
You can use D private with Java-like "only for members functions" meaning by putting it alone in it's module, if you want.
May 11 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Friday, 11 May 2018 at 09:47:39 UTC, Dukc wrote:
 On Friday, 11 May 2018 at 04:43:09 UTC, KingJoffrey wrote:
 On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 `private` is for outside the module. Within the module, 
 private is not applied because D wanted to avoid C++'s 
 `friend` functions.
'private' is "meant" to be part of the implementation of 'the class'. Whereas D makes it part of the implementation of 'the module' ( which is an even higher level of abstraction). This is an abomination! A class should have the capacity to protect its attributes/methods - even from the module.
You can use D private with Java-like "only for members functions" meaning by putting it alone in it's module, if you want.
Yes. I do know this. But that is essentially.. a hack. A 'private' declaration should be part of the implementation of the class, not the class+module. Some say this is just a philosphical difference - I say it's a key design issue for structured programming. A 'class' in D, should really be called a 'companion' (of the module), rather than a 'class', cause 'class' cannot truly implement it's own abstraction, but instead has its abstraction absorbed into the higher abstraction of the module. So now, in D, to understand the class, you must also understand the module. This is a backwards step in language design, in my opinion - for various reasons which are easy to examine further. When I can contain the class abstraction within the class, then I will begin to take D more seriously. Perhaps this is why some say 'idiomatic' D does not really use classes (cause they haven't been implemented correctly anyway, so why bother using them).
May 11 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 11/05/2018 10:32 PM, KingJoffrey wrote:
 When I can contain the class abstraction within the class, then I will 
 begin to take D more seriously.
 
 Perhaps this is why some say 'idiomatic' D does not really use classes 
 (cause they haven't been implemented correctly anyway, so why bother 
 using them).
We have vastly different views on the subject. Classes are expensive, not everybody wants to pay for what it gives in all situations.
May 11 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Friday, 11 May 2018 at 10:43:19 UTC, rikki cattermole wrote:
 Classes are expensive, not everybody wants to pay for what it 
 gives in all situations.
Mmm...that claim is so broad is to be meaningless. Good memory allocation algorithms, intelligent optimising compilers/runtimes, prudent use of class inheritance and other features, etc..etc.... all this can change performance one way or the other. Programs that do not use classes can (very easily) become poor peforming too. Anyway... nice way for you to sidetrack my argument ;-) (which is about correcting, the incorrect implementation of class enscapsulation in D - so I can start using it).
May 11 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 11/05/2018 11:25 PM, KingJoffrey wrote:
 On Friday, 11 May 2018 at 10:43:19 UTC, rikki cattermole wrote:
 Classes are expensive, not everybody wants to pay for what it gives in 
 all situations.
Mmm...that claim is so broad is to be meaningless. Good memory allocation algorithms, intelligent optimising compilers/runtimes, prudent use of class inheritance and other features, etc..etc.... all this can change performance one way or the other. Programs that do not use classes can (very easily) become poor peforming too. Anyway... nice way for you to sidetrack my argument ;-) (which is about correcting, the incorrect implementation of class enscapsulation in D - so I can start using it).
Well then, since you don't like how it is now, lets see the DIP.
May 11 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Friday, 11 May 2018 at 11:37:17 UTC, rikki cattermole wrote:
 Well then, since you don't like how it is now, lets see the DIP.
it deserves to treated as a 'bug', not an DIP.
May 11 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 12/05/2018 12:23 AM, KingJoffrey wrote:
 On Friday, 11 May 2018 at 11:37:17 UTC, rikki cattermole wrote:
 Well then, since you don't like how it is now, lets see the DIP.
it deserves to treated as a 'bug', not an DIP.
It works as designed. There is no bug here. Make a DIP please.
May 11 2018
parent reply Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
Might I suggest going back to the sealed classes topic? I don't 
think the discussion in this thread should go in the direction 
about the sense of using classes, proper encapsulation and the 
memory related stuff.
May 11 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Friday, 11 May 2018 at 12:59:21 UTC, Piotr Mitana wrote:
 Might I suggest going back to the sealed classes topic? I don't 
 think the discussion in this thread should go in the direction 
 about the sense of using classes, proper encapsulation and the 
 memory related stuff.
Actually, it is completely on topic. (although I understand that many on this forum are very eager to shut down any discussion about fixing class encapsulation in D, for some reason). i.e, to be more specific.. so you can understand...my reply to 'do I want sealed classes in D', is simply no. What I want first, is a class that can properly encapsulate itself. Until that occurs, any talk about expanding the class concept with yet more attributes (that probably won't mean what you think they mean), like sealed, is just irrelevant and pushes the problem of broken encapsulation even further down peoples code paths. private is not private at all in D, and because of this, classes are fundamentally broken in D (by design apparently). Now.. I really do have better ways to spend my time. I've made my point. Nobody who uses D seems to think in a similar way, apparently, so I leave it at that.
May 11 2018
next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Friday, 11 May 2018 at 14:05:25 UTC, KingJoffrey wrote:
 [snip]

 Actually, it is completely on topic. (although I understand 
 that many on this forum are very eager to shut down any 
 discussion about fixing class encapsulation in D, for some 
 reason).

 i.e, to be more specific.. so you can understand...my reply to 
 'do I want sealed classes in D', is simply no. What I want 
 first, is a class that can properly encapsulate itself.

 Until that occurs, any talk about expanding the class concept 
 with yet more attributes (that probably won't mean what you 
 think they mean), like sealed, is just irrelevant and pushes 
 the problem of broken encapsulation even further down peoples 
 code paths.

 private is not private at all in D, and because of this, 
 classes are fundamentally broken in D (by design apparently).

 Now.. I really do have better ways to spend my time. I've made 
 my point. Nobody who uses D seems to think in a similar way, 
 apparently, so I leave it at that.
I think the last point in the conversation was "write a DIP". Nothing is going to change unless someone does that. Personally, I don't agree with the idiomatic D doesn't use classes much argument. If that's the case, then they should be removed from the language. The language supports OOP/inheritance and if this is something that makes that experience better, then let it stand on its merits. But a new keyword will not get added without a DIP.
May 11 2018
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, May 11, 2018 15:02:08 jmh530 via Digitalmars-d wrote:
 I think the last point in the conversation was "write a DIP".
 Nothing is going to change unless someone does that.

 Personally, I don't agree with the idiomatic D doesn't use
 classes much argument. If that's the case, then they should be
 removed from the language. The language supports OOP/inheritance
 and if this is something that makes that experience better, then
 let it stand on its merits. But a new keyword will not get added
 without a DIP.
D supports OOP, and OOP should work. It's just that if most code isn't using classes much, then adding features specific to OOP isn't as valuable and may not be worth the extra complication it adds to the language. However, if a solid enough use case is presented in a DIP, then it could be added. The fact that a feature relates to classes definitely doesn't make it a guarantee that it's not worth having. It just reduces its overall value and makes it so that it's likely going to need to present a stronger case than a feature that helps a lot more code might. Ultimately though, it comes down to how good the arguments and use cases presented in the DIP are and how Walter and Andrei feel about it. And even if a feature were highly likely to be accepted if a DIP were written, if a DIP isn't written, then it isn't happening. So, if someone feels strongly about a potential feature (whatever that feature may be), and they want it in the language, they need to put in the time and effort to write a solid DIP. Discussing it may help improve the DIP, but ultimately, it's the DIP and how Andrei and Walter react to it that matters. - Jonathan M Davis
May 11 2018
prev sibling parent Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
On Friday, 11 May 2018 at 15:02:08 UTC, jmh530 wrote:
 But a new keyword will not get added without a DIP.
Yes, I know it definitely needs a DIP - I've opened a discussion in order to gather community members' opinions on sealed and decide whether to write this DIP at all and possibly track down some concept issues at the very beginning.
May 11 2018
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 11 May 2018 at 14:05:25 UTC, KingJoffrey wrote:

 private is not private at all in D, and because of this, 
 classes are fundamentally broken in D (by design apparently).

 Now.. I really do have better ways to spend my time. I've made 
 my point. Nobody who uses D seems to think in a similar way, 
 apparently, so I leave it at that.
Classes are *not* broken in D. The module is the lowest level of encapsulation and provides exactly what encapsulation is supposed to provide -- the ability to hide the implementation from the outside world so that it may be changed without breaking the API. Being able to access private class members in the same module does not break encapsulation. If you make a change to the class that breaks something in the module, you have access to the module to fix what is broken. It's no different than what happens when you break code in the class itself, e.g this: ``` module m; class Foo { private int x; } void manipFoo(Foo f) { f.x += 1; } ``` is no different than this: ``` module m; class Foo { private int x; void manip() { x += 1; } } ``` In both case, a change to the name or type of x can break the local functions and, in both cases, the person changing x has access to the local functions to fix the breakage. I don't see how putting the function outside or inside the class declaration makes any difference.
May 11 2018
next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 11 May 2018 at 16:51:30 UTC, Mike Parker wrote:
 I don't see  how putting the function outside or inside
 the class declaration makes any difference.
Being inside the class takes up a vtable slot and is inheritable. In terms of encapsulation there is no difference.
May 11 2018
prev sibling parent reply rumbu <rumbu rumbu.ro> writes:
On Friday, 11 May 2018 at 16:51:30 UTC, Mike Parker wrote:
 On Friday, 11 May 2018 at 14:05:25 UTC, KingJoffrey wrote:

 private is not private at all in D, and because of this, 
 classes are fundamentally broken in D (by design apparently).

 Now.. I really do have better ways to spend my time. I've made 
 my point. Nobody who uses D seems to think in a similar way, 
 apparently, so I leave it at that.
Classes are *not* broken in D. The module is the lowest level of encapsulation and provides exactly what encapsulation is supposed to provide -- the ability to hide the implementation from the outside world so that it may be changed without breaking the API. Being able to access private class members in the same module does not break encapsulation.
Yes, it does. The first example is unit testing. Having access to the private members of a class inside the same module is a mistake because it breaks the idea of encapsulation. Unit testing must be done exclusively on public members of a class. If you are feeling the urge to test a class private thing, there is something wrong with your class design. In the parallel world of true OOP which D tries to avoid as much as possible there is a saying for that: "Everytime you test a private method, a unicorn dies". The second example is inter-class access of private members if you have multiple classes in the same module. The "define a class per module" is not a solution in this case because D lacks the idea of namespace an it's just ridiculous to have a library with 1000 different modules just to achieve real class encapsulation. The third example is pollution of IDE code completion in the same module with members which are not meant to be there.
May 11 2018
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, May 11, 2018 19:45:10 rumbu via Digitalmars-d wrote:
 On Friday, 11 May 2018 at 16:51:30 UTC, Mike Parker wrote:
 On Friday, 11 May 2018 at 14:05:25 UTC, KingJoffrey wrote:
 private is not private at all in D, and because of this,
 classes are fundamentally broken in D (by design apparently).

 Now.. I really do have better ways to spend my time. I've made
 my point. Nobody who uses D seems to think in a similar way,
 apparently, so I leave it at that.
Classes are *not* broken in D. The module is the lowest level of encapsulation and provides exactly what encapsulation is supposed to provide -- the ability to hide the implementation from the outside world so that it may be changed without breaking the API. Being able to access private class members in the same module does not break encapsulation.
Yes, it does. The first example is unit testing. Having access to the private members of a class inside the same module is a mistake because it breaks the idea of encapsulation. Unit testing must be done exclusively on public members of a class. If you are feeling the urge to test a class private thing, there is something wrong with your class design. In the parallel world of true OOP which D tries to avoid as much as possible there is a saying for that: "Everytime you test a private method, a unicorn dies".
I completely disagree with this. Testing private functions can be extremely valuable for ensuring that everything within the type functions the way that it should and can often lead to much better testing of how pieces of a type work, because you have better control over what's going on at that exact point in the call chain when you're testing it directly. I don't see how the access level of a function has anything to do with whether it makes sense to test it beyond the fact that it's more important that public functions be tested, because that's what users are going to be calling. But well-tested private functions help ensure that public functions work correctly, especially when a private function is used by multiple public functions - just like you want the functions that you're calling from other modules to work correctly even though they're not part of the public API of this type or module. I do not understand how anyone could argue that testing private functions is a bad idea. - Jonathan M Davis
May 11 2018
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, May 11, 2018 at 02:04:34PM -0600, Jonathan M Davis via Digitalmars-d
wrote:
 On Friday, May 11, 2018 19:45:10 rumbu via Digitalmars-d wrote:
[...]
 The first example is unit testing. Having access to the private
 members of a class inside the same module is a mistake because it
 breaks the idea of encapsulation. Unit testing must be done
 exclusively on public members of a class. If you are feeling the
 urge to test a class private thing, there is something wrong with
 your class design. In the parallel world of true OOP which D tries
 to avoid as much as possible there is a saying for that: "Everytime
 you test a private method, a unicorn dies".
I completely disagree with this. Testing private functions can be extremely valuable for ensuring that everything within the type functions the way that it should and can often lead to much better testing of how pieces of a type work, because you have better control over what's going on at that exact point in the call chain when you're testing it directly.
Yeah, in my own projects I have found that unittesting private functions has been a life-saver in catching bugs early (especially if you're writing a complex class / struct / type / module with many moving parts), ensuring helper functions actually work, and also building confidence that the code is actually doing what you think it's doing. Testing only the external API means I have to write a ton of code before a single test can be run, which means a lot more places for bugs to hide and a lot more time wasted trying to locate a bug buried deep within several levels of function calls under the public API. If it's true that a unicorn dies everytime I test a private method, then I say, kill 'em all off, they deserve to go extinct! (None of this negates the fact that public APIs need to be thoroughly tested, of course. Like Jonathan, I just don't see how one could argue that private methods should *not* be tested.) T -- Study gravitation, it's a field with a lot of potential.
May 11 2018
parent reply rumbu <rumbu rumbu.ro> writes:
On Friday, 11 May 2018 at 20:22:52 UTC, H. S. Teoh wrote:
 On Fri, May 11, 2018 at 02:04:34PM -0600, Jonathan M Davis via 
 Digitalmars-d wrote:
 On Friday, May 11, 2018 19:45:10 rumbu via Digitalmars-d wrote:
[...]
 The first example is unit testing. Having access to the 
 private members of a class inside the same module is a 
 mistake because it breaks the idea of encapsulation. Unit 
 testing must be done exclusively on public members of a 
 class. If you are feeling the urge to test a class private 
 thing, there is something wrong with your class design. In 
 the parallel world of true OOP which D tries to avoid as 
 much as possible there is a saying for that: "Everytime you 
 test a private method, a unicorn dies".
I completely disagree with this. Testing private functions can be extremely valuable for ensuring that everything within the type functions the way that it should and can often lead to much better testing of how pieces of a type work, because you have better control over what's going on at that exact point in the call chain when you're testing it directly.
Yeah, in my own projects I have found that unittesting private functions has been a life-saver in catching bugs early (especially if you're writing a complex class / struct / type / module with many moving parts), ensuring helper functions actually work, and also building confidence that the code is actually doing what you think it's doing. Testing only the external API means I have to write a ton of code before a single test can be run, which means a lot more places for bugs to hide and a lot more time wasted trying to locate a bug buried deep within several levels of function calls under the public API. If it's true that a unicorn dies everytime I test a private method, then I say, kill 'em all off, they deserve to go extinct! (None of this negates the fact that public APIs need to be thoroughly tested, of course. Like Jonathan, I just don't see how one could argue that private methods should *not* be tested.) T
I never said that. Feel free to test your private methods as long as you want it if you think that will improve your code correctness. But for *me* this is a bad practice. Every time I am in a situation that will result in such need, I question myself if there is something wrong with my class design and usually I end with extracting that private functionality to another class that can be tested. Testing private functionality means that you *lock* the internal implementation of your class. If you decide later to change the implementation, your previous tests will have zero-value. On the contrary, testing public functionality of a class will *lock* the design and this is desirable at least from a library design point of view. The difference here is that D is offering you the means to code your stuff exactly as you want it, but the same is not true for my way of coding. And this is really annoying when you are doing TDD where the public testing of a class is in fact the definition of functionality and I don't want to touch by mistake any private member in the process. class SquareRoot { private void someComplicatedAlgorithm { ... } public void calculate() { ... someComplicatedAlgorithm() ... } } unittest { //assert something about someComplicatedAlgorithm.... //and so on. } Let's suppose that one day I will change someComplicatedAlgorithm and most of the assertions will not be satisfied. That moment I have two options: modify all my assertions to match or completely delete them, hence the zero-value of them. It will not be better to limit my assertions to calculate() instead?
May 11 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, May 12, 2018 06:42:24 rumbu via Digitalmars-d wrote:
 On Friday, 11 May 2018 at 20:22:52 UTC, H. S. Teoh wrote:
 On Fri, May 11, 2018 at 02:04:34PM -0600, Jonathan M Davis via

 Digitalmars-d wrote:
 On Friday, May 11, 2018 19:45:10 rumbu via Digitalmars-d wrote:
[...]
 The first example is unit testing. Having access to the
 private members of a class inside the same module is a
 mistake because it breaks the idea of encapsulation. Unit
 testing must be done exclusively on public members of a
 class. If you are feeling the urge to test a class private
 thing, there is something wrong with your class design. In
 the parallel world of true OOP which D tries to avoid as
 much as possible there is a saying for that: "Everytime you
 test a private method, a unicorn dies".
I completely disagree with this. Testing private functions can be extremely valuable for ensuring that everything within the type functions the way that it should and can often lead to much better testing of how pieces of a type work, because you have better control over what's going on at that exact point in the call chain when you're testing it directly.
Yeah, in my own projects I have found that unittesting private functions has been a life-saver in catching bugs early (especially if you're writing a complex class / struct / type / module with many moving parts), ensuring helper functions actually work, and also building confidence that the code is actually doing what you think it's doing. Testing only the external API means I have to write a ton of code before a single test can be run, which means a lot more places for bugs to hide and a lot more time wasted trying to locate a bug buried deep within several levels of function calls under the public API. If it's true that a unicorn dies everytime I test a private method, then I say, kill 'em all off, they deserve to go extinct! (None of this negates the fact that public APIs need to be thoroughly tested, of course. Like Jonathan, I just don't see how one could argue that private methods should *not* be tested.) T
I never said that. Feel free to test your private methods as long as you want it if you think that will improve your code correctness. But for *me* this is a bad practice. Every time I am in a situation that will result in such need, I question myself if there is something wrong with my class design and usually I end with extracting that private functionality to another class that can be tested. Testing private functionality means that you *lock* the internal implementation of your class. If you decide later to change the implementation, your previous tests will have zero-value. On the contrary, testing public functionality of a class will *lock* the design and this is desirable at least from a library design point of view. The difference here is that D is offering you the means to code your stuff exactly as you want it, but the same is not true for my way of coding. And this is really annoying when you are doing TDD where the public testing of a class is in fact the definition of functionality and I don't want to touch by mistake any private member in the process. class SquareRoot { private void someComplicatedAlgorithm { ... } public void calculate() { ... someComplicatedAlgorithm() ... } } unittest { //assert something about someComplicatedAlgorithm.... //and so on. } Let's suppose that one day I will change someComplicatedAlgorithm and most of the assertions will not be satisfied. That moment I have two options: modify all my assertions to match or completely delete them, hence the zero-value of them. It will not be better to limit my assertions to calculate() instead?
That's your choice, but even if you decided to refactor in a way that it made sense to throw away all of the tests for a private function, at least it was well-tested up to that point, and the tests had value as long as they made sense. Personally, I would _much_ rather be very thorough with my tests and then later have to seriously rework existing tests or throw them away when I refactor than to not have thorough testing. And my experience is that if a private function is anything other than really short and simple, having tests for it catches bugs and improves the quality of my code, regardless of whatever refactoring I may or may not do later. You obviously don't have to test your private functions if you don't want to, but if you're trying to state that testing private functions is bad practice (and that's very much what it seemed like you were saying when you talked about testing private functions killing unicorns), then I'm very much going to disagree - especially in cases where the public API is relatively simple but does a lot of stuff underneath the hood. - Jonathan M Davis
May 12 2018
parent rumbu <rumbu rumbu.ro> writes:
On Saturday, 12 May 2018 at 07:07:33 UTC, Jonathan M Davis wrote:

 You obviously don't have to test your private functions if you 
 don't want to, but if you're trying to state that testing 
 private functions is bad practice (and that's very much what it 
 seemed like you were saying when you talked about testing 
 private functions killing unicorns), [...]
Actually Jim Weirich (Rake's creator) at one of Ruby's conferences had a coffee mug with "Every time you test a private method, an unicorn dies".
May 12 2018
prev sibling parent Neia Neutuladh <neia ikeran.org> writes:
On Saturday, 12 May 2018 at 06:42:24 UTC, rumbu wrote:
 Testing private functionality means that you *lock* the 
 internal implementation of your class. If you decide later to 
 change the implementation, your previous tests will have 
 zero-value.
I did TDD at a company for three years. Tests didn't survive refactoring. These days, I have tests to ensure correctness, and they can tell me when public interfaces change. I usually don't need tests to tell me that, but they help just in case. I also tend to have examples projects for anything more complex, which reduces the amount of trouble I can get myself into. Plus the majority of my code is in applications rather than libraries, so consistent interfaces aren't nearly as important (as long as static typing catches the majority of incorrect calls and contracts catch the rest).
May 12 2018
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 11 May 2018 at 19:45:10 UTC, rumbu wrote:

 The first example is unit testing. Having access to the private 
 members of a class inside the same module is a mistake because 
 it breaks the idea of encapsulation. Unit testing must be done 
 exclusively on public members of a class. If you are feeling 
 the urge to test a class private thing, there is something 
 wrong with your class design. In the parallel world of true OOP 
 which D tries to avoid as much as possible there is a saying 
 for that: "Everytime you test a private method, a unicorn dies".
My point is that it *doesn't* break encapsulation. The *module* is the lowest level of encapsulation, not the class. The public API is not affected by any changes internal to the module. And, like Jonathan, I disagree with the assertion that private members shouldn't be tested.
 The second example is inter-class access of private members if 
 you have multiple classes in the same module. The "define a 
 class per module" is not a solution in this case because D 
 lacks the idea of namespace an it's just ridiculous to have a 
 library with 1000 different modules just to achieve real class 
 encapsulation.
Again, they're in the same module. From an encapsulation stand point, what does it matter that private members are within or without any specific set of curly braces? It only matters if you want to adhere to a purely conceptual view of encapsulation. From a practical view, it matters not one whit.
 The third example is pollution of IDE code completion in the 
 same module with members which are not meant to be there.
If they're in the same module, then they're meant to be there.
May 11 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Saturday, 12 May 2018 at 00:39:29 UTC, Mike Parker wrote:
 Again, they're in the same module. From an encapsulation stand 
 point, what does it matter that private members are within or 
 without any specific set of curly braces? It only matters if 
 you want to adhere to a purely conceptual view of 
 encapsulation. From a practical view, it matters not one whit.


It matters, in the same sense, that it matters if you have a module, full of functions (which are encapsulated units of code), but your module has a whole bunch of goto statements (not necessarily within a function). Now...you've essentially no idea now which functions are truly encapsulated, and which aren't. You now have to take into view, 'the whole module' - which goes against the very principle of problem solving by breaking down the problem into smaller pieces. I have looked a D source code modules. I challenge anyone to get there head around whole modules. In a similar vain to gotos, having classes (which are traditionally meant to be encapsulated units of code) in a module, but also having anything in the module (outside of the class[es]), having the capacity to do whatever it wants to the private parts of the class. We're back in goto land!
May 11 2018
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 12/05/2018 3:02 PM, KingJoffrey wrote:
 On Saturday, 12 May 2018 at 00:39:29 UTC, Mike Parker wrote:
 Again, they're in the same module. From an encapsulation stand point, 
 what does it matter that private members are within or without any 
 specific set of curly braces? It only matters if you want to adhere to 
 a purely conceptual view of encapsulation. From a practical view, it 
 matters not one whit.


It matters, in the same sense, that it matters if you have a module, full of functions (which are encapsulated units of code), but your module has a whole bunch of goto statements (not necessarily within a function). Now...you've essentially no idea now which functions are truly encapsulated, and which aren't. You now have to take into view, 'the whole module' - which goes against the very principle of problem solving by breaking down the problem into smaller pieces. I have looked a D source code modules. I challenge anyone to get there head around whole modules.
Its actually pretty easy. I have yet to find a D module I couldn't understand. Now IntelliJ IDEA on the other hand... I gave up on my recent iteration of a plugin for D when discovering I really did not understand how its setup enough to add something to the configuration dialog. Let alone SDK and what not.
May 11 2018
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/11/2018 8:02 PM, KingJoffrey wrote:
 On Saturday, 12 May 2018 at 00:39:29 UTC, Mike Parker wrote:
 Again, they're in the same module. From an encapsulation stand point, what 
 does it matter that private members are within or without any specific set of 
 curly braces? It only matters if you want to adhere to a purely conceptual 
 view of encapsulation. From a practical view, it matters not one whit.


It matters, in the same sense, that it matters if you have a module, full of functions (which are encapsulated units of code), but your module has a whole bunch of goto statements (not necessarily within a function). Now...you've essentially no idea now which functions are truly encapsulated, and which aren't.
Mike's right. D's encapsulation model is designed around the module. If a module is too large to be comprehended, it should be broken up into smaller modules, each with its encapsulated functionality.
May 12 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Saturday, 12 May 2018 at 13:38:18 UTC, Walter Bright wrote:
 Mike's right. D's encapsulation model is designed around the 
 module.
Actually, that is not true. If it were true, then I could do: ------------ module test; void main() { i = 2; } // sorry, but i belongs to another unit of encapsulation void foo() { int i = 1; } ------------ D only breaks the encapsulation properties of classes, not functions. Since the vast majority of programmers use classes as the basis for encapsulation, this surely presents a significant problem to those coming over to D, rightly expecting that encapsulation to be retained.
 If a module is too large to be comprehended, it should be 
 broken up into smaller modules, each with its encapsulated 
 functionality.
But that's why we have functions and classes - which are their own level of smaller units of encapsulation. Blurring the boundary of encapsulation seems like a big step backward in terms of structured programming. Each unit of code (a function, a class, a module) should respect the encapsulation properties of each other. There's simply no point in using classes in D, as they have no capacity to encapsulate themselves (whereas function still retain this privilege) Now if 'private' meant 'private to the class' (as most people would rightly expect), and the default if you had no attribute was, say, 'accessible to the module', then I could probably live with that, and I would start to use classes in D productively. But when the class has lost its capacity to encapsulate, it's lost its purpose. It is hard enough to hold a class in working memory so you can reason about. Making us hold whole modules in memory so we can reason about the interaction between classes and modules, is just nonsense, in my opinion.
May 12 2018
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Saturday, 12 May 2018 at 15:48:53 UTC, KingJoffrey wrote:

 Actually, that is not true. If it were true, then I could do:

 ------------
 module test;
 void main() { i = 2; }  // sorry, but i belongs to another unit 
 of encapsulation
 void foo() { int i = 1; }
 ------------

 D only breaks the encapsulation properties of classes, not 
 functions.
 But that's why we have functions and classes - which are their 
 own level of smaller units of encapsulation. Blurring the 
 boundary of encapsulation seems like a big step backward in 
 terms of structured programming.

 Each unit of code (a function, a class, a module) should 
 respect the encapsulation properties of each other.
Encapsulation and scope are not the same thing.
 There's simply no point in using classes in D, as they have no 
 capacity to encapsulate themselves
Yes, they do. The private API is not visible to the outside world.
 Now if 'private' meant 'private to the class' (as most people 
 would rightly expect), and the default if you had no attribute 
 was, say, 'accessible to the module', then I could probably 
 live with that, and I would start to use classes in D 
 productively.
I'm using classes productively right now. Having private class members accessible in the module is a boon, not a hindrance, IMO.
 But when the class has lost its capacity to encapsulate, it's 
 lost its purpose.
It hasn't lost its ability to encapsulate. The private implementation is hidden from the outside world and does not impact the public API.
 Making us hold whole modules in memory so we can reason about 
 the interaction between classes and modules, is just nonsense, 
 in my opinion.
No, nonsense would look like this: ``` module mymmod; class Foo { private int _x; /* module private */ int x() { return _x; } } class Bar { private int _y; /* module private */ int y() { return _y; } } void printFooBar(Foo f, Bar b) { import std.stdio : writefln; writefln("f.x = %s, b.y = %s", f.x, b.y); } ``` Thank goodness we don't have to do this silliness.
May 12 2018
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/12/2018 9:42 AM, Mike Parker wrote:
 Thank goodness we don't have to do this silliness.
I always thought the 'friend' business in C++ was an awful hack. But C++ didn't have modules, and modules are a much better solution to that problem.
May 12 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Saturday, 12 May 2018 at 18:36:59 UTC, Walter Bright wrote:
 On 5/12/2018 9:42 AM, Mike Parker wrote:
 Thank goodness we don't have to do this silliness.
I always thought the 'friend' business in C++ was an awful hack. But C++ didn't have modules, and modules are a much better solution to that problem.
Modules would only be a better solution, if, and only if, the programmer still had control over class level encapsulation. At least 'friend' in c++, is in the control of the programmer. D has decided the programmer doesn't need this control anymore, takes that control away, and gives it to the module - the programmer has no say in it - even if the programmer want's it private, the module overrides private!! I would expect, that like me, 10's of millions of other programmers would not be comfortable with this. That the '< 1000' D programmers think otherwise, doesn't make the case. Go back and give the programmer control, as to whether the class or the module has the greater authority, and perhaps...then... D will attract more programmers. programmers out there - I'm sure they'll love what D has done with the class-module interaction. ================================ module test; import std.stdio : writeln; void main() { Person p = new Person("King Joffrey"); writeln(p.getName); // I designed my class to present this interface. writeln(p._name); // The module couldn't care less about your interface. p._name = "King Walter"; // even worse, the module can de-throne the king!! writeln(p._name); } class Person { private string _name; public void setName(string name) { this._name = name; } public string getName() { return ProperName(this._name); } public this(string name) { _name = name; } private static string ProperName(string name) { return name ~ " : The one true king!"; } } ===========================================
May 12 2018
parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Sunday, 13 May 2018 at 01:52:20 UTC, KingJoffrey wrote:
 On Saturday, 12 May 2018 at 18:36:59 UTC, Walter Bright wrote:
 On 5/12/2018 9:42 AM, Mike Parker wrote:
 Thank goodness we don't have to do this silliness.
[...]
================================ module test; import std.stdio : writeln; void main() { Person p = new Person("King Joffrey"); writeln(p.getName); // I designed my class to present this interface. writeln(p._name); // The module couldn't care less about your interface. p._name = "King Walter"; // even worse, the module can de-throne the king!! writeln(p._name); } class Person { private string _name; public void setName(string name) { this._name = name; } public string getName() { return ProperName(this._name); } public this(string name) { _name = name; } private static string ProperName(string name) { return name ~ " : The one true king!"; } } ===========================================
Again, all you have to do is put class Person in a separate module. Its not that hard. Why is main in the same module if it isn't logically related to Person? It should be in its own module. Its uses Person. main does not extend person, it needs only the public bits. So it goes in its own module. And please, if this bothers you so much, start a new thread. You're spamming someone else's feature request by going off topic.
May 12 2018
next sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Sunday, 13 May 2018 at 02:10:31 UTC, Uknown wrote:
 And please, if this bothers you so much, start a new thread. 
 You're spamming someone else's feature request by going off 
 topic.
yeah, I know how much *you* (and many others) would like to shutdown any discussion about the absurd way in which classes are treated in D. It's a touchy topic it seems. Now, if I were having this discussion with myself, your comment about spamming the topic 'might' be correct. As it is though, everyone involved in the discussion, including yourself, is spamming the topic, in that case. so take your own advice. create a new thread, and have a go at me there instead. When someone creates a topic about extending the capacity of classes in D, I will always feel the urge to remind them, that classes in D are a complete joke - and that you shouldn't bother using them. Better to use another language that has the capacity to respect the encapsulation barrier of the class.
May 12 2018
parent reply Neia Neutuladh <neia ikeran.org> writes:
On Sunday, 13 May 2018 at 02:36:28 UTC, KingJoffrey wrote:
 On Sunday, 13 May 2018 at 02:10:31 UTC, Uknown wrote:
 And please, if this bothers you so much, start a new thread. 
 You're spamming someone else's feature request by going off 
 topic.
yeah, I know how much *you* (and many others) would like to shutdown any discussion about the absurd way in which classes are treated in D. It's a touchy topic it seems.
Nobody's getting worked up about this, and nobody's telling you to stop talking about it. There have been suggestions that you write up a DIP for it. This is a standard process for suggesting improvements to D. I have a draft DIP hanging around on my hard drive relating to named function parameters, for instance. It discusses: * The thing to be changed * Why I think it should be changed * Examples of how the status quo causes problems * How I want code to work in the future * Examples of what I want code to look like * How other languages handle this thing That's just due diligence for nontrivial enhancement requests. And named function parameters is a feature with probably very little opposition and moderate support.
 so take your own advice. create a new thread, and have a go at 
 me there instead.
It should be as easy as changing the "Subject" field on the reply screen. It would have been gracious of you to do this, all things considered.
 When someone creates a topic about extending the capacity of 
 classes in D, I will always feel the urge to remind them, that 
 classes in D are a complete joke - and that you shouldn't 
 bother using them. Better to use another language that has the 
 capacity to respect the encapsulation barrier of the class.
Your complaint is about protection, not about classes. It should affect all definitions. Perhaps you simply don't expect type-level encapsulation for structs and top-level declarations.
May 12 2018
next sibling parent Neia Neutuladh <neia ikeran.org> writes:
On Sunday, 13 May 2018 at 05:11:16 UTC, Neia Neutuladh wrote:
 It should be as easy as changing the "Subject" field on the 
 reply screen.
Apparently not. My apologies.
May 12 2018
prev sibling next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 13/05/2018 5:11 PM, Neia Neutuladh wrote:
 On Sunday, 13 May 2018 at 02:36:28 UTC, KingJoffrey wrote:
 On Sunday, 13 May 2018 at 02:10:31 UTC, Uknown wrote:
 And please, if this bothers you so much, start a new thread. You're 
 spamming someone else's feature request by going off topic.
yeah, I know how much *you* (and many others) would like to shutdown any discussion about the absurd way in which classes are treated in D. It's a touchy topic it seems.
Nobody's getting worked up about this, and nobody's telling you to stop talking about it. There have been suggestions that you write up a DIP for it. This is a standard process for suggesting improvements to D. I have a draft DIP hanging around on my hard drive relating to named function parameters, for instance. It discusses: * The thing to be changed * Why I think it should be changed * Examples of how the status quo causes problems * How I want code to work in the future * Examples of what I want code to look like * How other languages handle this thing That's just due diligence for nontrivial enhancement requests. And named function parameters is a feature with probably very little opposition and moderate support.
 so take your own advice. create a new thread, and have a go at me 
 there instead.
It should be as easy as changing the "Subject" field on the reply screen. It would have been gracious of you to do this, all things considered.
 When someone creates a topic about extending the capacity of classes 
 in D, I will always feel the urge to remind them, that classes in D 
 are a complete joke - and that you shouldn't bother using them. Better 
 to use another language that has the capacity to respect the 
 encapsulation barrier of the class.
Your complaint is about protection, not about classes. It should affect all definitions. Perhaps you simply don't expect type-level encapsulation for structs and top-level declarations.
On that note we should chat[0]. Preferably IRC or Discord. [0] https://github.com/rikkimax/DIPs/blob/named_args/DIPs/DIP1xxx-RC.md
May 12 2018
prev sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Sunday, 13 May 2018 at 05:11:16 UTC, Neia Neutuladh wrote:
 Nobody's getting worked up about this, and nobody's telling you 
 to stop talking about it. There have been suggestions that you 
 write up a DIP for it. This is a standard process for 
 suggesting improvements to D.

 Your complaint is about protection, not about classes. It 
 should affect all definitions. Perhaps you simply don't expect 
 type-level encapsulation for structs and top-level declarations.
First, this thread was about extending the capabilities of classes in D with some new attribute/capability - sealed. I thought it was first important to point out, in this thread, as opposed to a separate thread, that classes in D are already problematic, because modules do not respect the encapsulation boundaries of classes, and any discussion about further extending classes should be approached with great caution - because the problem will only become even more entrenched. Second, writing a DIP is pointless, since Walter likes the idea that the module doesn't protect the encapsulation boundary of the class. Now if Walter thinks that's fine, what is a DIP going to do? I mean really. I have better things to do. Third, those who responded to my caution are the ones that should have created a separate thread, not me. Finally (and I do mean finally), my concern about the loss of the encapsulation boundary of classes in D, has a very real impact on the quality and maintainability of software systems developed in D. That the designer of D apparently thinks otherwise, baffles me.
May 12 2018
next sibling parent bauss <jj_1337 live.dk> writes:
On Sunday, 13 May 2018 at 05:51:07 UTC, KingJoffrey wrote:
 On Sunday, 13 May 2018 at 05:11:16 UTC, Neia Neutuladh wrote:
 Nobody's getting worked up about this, and nobody's telling 
 you to stop talking about it. There have been suggestions that 
 you write up a DIP for it. This is a standard process for 
 suggesting improvements to D.

 Your complaint is about protection, not about classes. It 
 should affect all definitions. Perhaps you simply don't expect 
 type-level encapsulation for structs and top-level 
 declarations.
First, this thread was about extending the capabilities of classes in D with some new attribute/capability - sealed. I thought it was first important to point out, in this thread, as opposed to a separate thread, that classes in D are already problematic, because modules do not respect the encapsulation boundaries of classes, and any discussion about further extending classes should be approached with great caution - because the problem will only become even more entrenched. Second, writing a DIP is pointless, since Walter likes the idea that the module doesn't protect the encapsulation boundary of the class. Now if Walter thinks that's fine, what is a DIP going to do? I mean really. I have better things to do. Third, those who responded to my caution are the ones that should have created a separate thread, not me. Finally (and I do mean finally), my concern about the loss of the encapsulation boundary of classes in D, has a very real impact on the quality and maintainability of software systems developed in D. That the designer of D apparently thinks otherwise, baffles me.
Walter is not the only person who accepts DIP and although he's the core head of D, it doesn't mean all his opinions are strictly 100% how D is going to evolve. I'm sure there are plenty of features that has been implemented that he does not entirely agree with and the same goes for others. If you can write a DIP and have a good use case for it, other than a very rare usecase, then it would most likely be accepted, IF the language would benefit from the addition. Writing posts about how you don't like feature X is way more useless than a DIP, because it will NOT change anything.
May 13 2018
prev sibling parent reply meppl <mephisto nordhoff-online.de> writes:
On Sunday, 13 May 2018 at 05:51:07 UTC, KingJoffrey wrote:
 On Sunday, 13 May 2018 at 05:11:16 UTC, Neia Neutuladh wrote:
 [...]
First, this thread was about extending the capabilities of classes in D with some new attribute/capability - sealed. I thought it was first important to point out, in this thread, as opposed to a separate thread, that classes in D are already problematic, because modules do not respect the encapsulation boundaries of classes, and any discussion about further extending classes should be approached with great caution - because the problem will only become even more entrenched. Second, writing a DIP is pointless, since Walter likes the idea that the module doesn't protect the encapsulation boundary of the class. Now if Walter thinks that's fine, what is a DIP going to do? I mean really. I have better things to do. Third, those who responded to my caution are the ones that should have created a separate thread, not me. Finally (and I do mean finally), my concern about the loss of the encapsulation boundary of classes in D, has a very real impact on the quality and maintainability of software systems developed in D. That the designer of D apparently thinks otherwise, baffles me.
walter bright was not the only one who liked that idea of "only module level encapsulation". Its unfair to imply it like that. Also, someone may say: I can see what happens in one and the same file. If there are two classes/structs in one file, they are "friends" and I dont need the "friend"-keyword anymore. Thats an argument, too.
May 13 2018
parent reply rumbu <rumbu rumbu.ro> writes:
On Sunday, 13 May 2018 at 15:13:59 UTC, meppl wrote:

 Also, someone may say: I can see what happens in one and the 
 same file. If there are two classes/structs in one file, they 
 are "friends" and I dont need the "friend"-keyword anymore.
 Thats an argument, too.
So, when you have 1000 classes, you just create 1000 files just to "unfriend" them :)
May 13 2018
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, May 13, 2018 17:19:26 rumbu via Digitalmars-d wrote:
 On Sunday, 13 May 2018 at 15:13:59 UTC, meppl wrote:
 Also, someone may say: I can see what happens in one and the
 same file. If there are two classes/structs in one file, they
 are "friends" and I dont need the "friend"-keyword anymore.
 Thats an argument, too.
So, when you have 1000 classes, you just create 1000 files just to "unfriend" them :)
Which is basically what you get in Java, though no one should be putting 1000 classes in a single module anyway. But if you want to make it so that classes can't access each other's members while still making it possible to import them together, then all you have to do is have a module which publicly imports all of those other modules which have one class each. The only thing that you really lose with D's approach as opposed to friend is that D doesn't provide a way to mark something from another module as a friend. package at least partially solves that problem though. Really, what D went with is similar to what Java did, only it's more flexible, because it doesn't restrict what can go in a module, whereas Java only allows one public class per module and doesn't have any free functions. Ultimately, D's solution simplifies things over what C++ did with friends while giving you basically the same level of control. It's just that if you don't want something to be able to access the private members of a class or struct, that symbol must be in a separate module. So, if you _really_ don't want anything accessing the internals of your class or struct, but you want to be able to stick stuff in the same file, then that can get annoying, because you can't do that. But public imports let you make it so that you can still import them as one even if they're not actually in the same file, and many of us have found that having the default be that other stuff in the module can access the private members to be very useful - especially with regards to testing. I fully expect that if we added some sort of "super private" that really made it so that nothing outside a class or struct could access its members, almost no one would use it, and it wouldn't really solve much in the way of real problems, much as I'm sure that a few folks like KingJoffrey would be quite happy to have something like that. Ultimately, there are tradeoffs between what C++ did and what D did, and neither approach is perfect, so some folks are likely to be happier with one approach over the other, but overall, what D has done has worked extremely well for D. - Jonathan M Davis
May 13 2018
prev sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Sunday, 13 May 2018 at 17:19:26 UTC, rumbu wrote:
 On Sunday, 13 May 2018 at 15:13:59 UTC, meppl wrote:

 Also, someone may say: I can see what happens in one and the 
 same file. If there are two classes/structs in one file, they 
 are "friends" and I dont need the "friend"-keyword anymore.
 Thats an argument, too.
So, when you have 1000 classes, you just create 1000 files just to "unfriend" them :)
If you have 1000 classes in a single module, you have bigger problems than encapsulation. :p -- Simen
May 13 2018
prev sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Sunday, 13 May 2018 at 02:10:31 UTC, Uknown wrote:
 Again, all you have to do is put class Person in a separate 
 module.
This is such a nonsense solution. Why do you keep proposing it? Is this you way to effectively sweep the problem under the carpet? For me, a module presents the opportunity to group objects into a larger working unit. But since D does not respect the encapsulation of objects, one has to revert to your solution, or mine (which is, if you're solution to a problem requires the use of classes, then go use a progamming language that respects the encapsulation boundary of classes).
May 12 2018
prev sibling parent reply Dukc <ajieskola gmail.com> writes:
On Saturday, 12 May 2018 at 15:48:53 UTC, KingJoffrey wrote:
 On Saturday, 12 May 2018 at 13:38:18 UTC, Walter Bright wrote:
 Mike's right. D's encapsulation model is designed around the 
 module.
Actually, that is not true. If it were true, then I could do: ------------ module test; void main() { i = 2; } // sorry, but i belongs to another unit of encapsulation void foo() { int i = 1; } ------------
No, it would be like: ------------ module test; void main() { foo.i = 2; } of encapsulation void foo() { static int i = 1; } ------------ ...and I think there might be point in allowing that. Non-static members could also perhaps be accessed in case of fibers, but that would likely be tough to implement and/or complicate the runtime.
May 14 2018
parent reply Dukc <ajieskola gmail.com> writes:
On Monday, 14 May 2018 at 07:02:37 UTC, Dukc wrote:

 ------------
 module test;
 void main() { foo.i = 2; }
 of encapsulation
 void foo() { static int i = 1; }
 ------------
meant ------------ module test; void main() { foo.i = 2; } void foo() { static int i = 1; } ------------
May 14 2018
next sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Monday, 14 May 2018 at 07:03:35 UTC, Dukc wrote:
 ------------
 module test;
 void main() { foo.i = 2; }
 void foo() { static int i = 1; }
 ------------
nice, .. I like it... I mean who really needs a function interface anyway? D may as well just get rid of that encapsulation concept too, since the class interface is pretty much moot in D modules. Maybe.. we should even, just completely get rid of functions and classes - as well as all that other stupid so-called 'structured programming' crap, which just restricts us, and revert to 'real' programming - using just line numbers and goto statements. Then, finally, we programmers can do whatever we want again. Local reasoning...it's so old-school.
May 14 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Monday, 14 May 2018 at 07:44:00 UTC, KingJoffrey wrote:

 D may as well just get rid of that encapsulation concept too, 
 since the class interface is pretty much moot in D modules.

 Maybe.. we should even, just completely get rid of functions 
 and classes - as well as all that other stupid so-called 
 'structured programming' crap, which just restricts us, and 
 revert to 'real' programming - using just line numbers and goto 
 statements. Then, finally, we programmers can do whatever we 
 want again.

 Local reasoning...it's so old-school.
A slippery slope fallacy isn't helping your case. Write a DIP if it bothers you so much, as it changes the languages fundamentally. Alexander
May 14 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Monday, 14 May 2018 at 19:40:18 UTC, 12345swordy wrote:
 A slippery slope fallacy isn't helping your case. Write a DIP 
 if it bothers you so much, as it changes the languages 
 fundamentally.


 Alexander
If 'getting a module to respect the enscapsulation boundaries the programmer puts in place would change the language so 'fundamentally', then the language 'already' presents big problems for large complex application development. Little old me ranting about it in some DIP isn't going to do much. D is great for small, quick stuff though - I'll give it that. I enjoy using D for small stuff. should, and will, like me, get a nasty shock when they come over to D, and discover it my mistake, as I did. It was only through debugging my code, did I realise I had disprespected the boundaries I set up, because the module let me do it, and the compiler thought that's what I must have wanted. I simply could not have made that mistake in any of the other langauges I use. Clearly others take a different perspective on this issue, that's fine, I just don't get the case they're trying to make. It hasn't made any sense to me thus far. Removing respect for encapsulation boundaries, in order to avoiding the need for using C++ like 'friend', sounds a bit dodgy to me. No matter how much I think about it, I'd rather have those boundaries and be forced to use friends.
May 14 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Tuesday, 15 May 2018 at 00:28:42 UTC, KingJoffrey wrote:
 On Monday, 14 May 2018 at 19:40:18 UTC, 12345swordy wrote:
 A slippery slope fallacy isn't helping your case. Write a DIP 
 if it bothers you so much, as it changes the languages 
 fundamentally.


 Alexander
If 'getting a module to respect the enscapsulation boundaries the programmer puts in place would change the language so 'fundamentally', then the language 'already' presents big problems for large complex application development.
Evidence for this claim please.

Again write a DIP if this bothers you. You are not going to make any language changes by ranting about it on the forums.
May 14 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 02:00:17 UTC, 12345swordy wrote:
 On Tuesday, 15 May 2018 at 00:28:42 UTC, KingJoffrey wrote:
 On Monday, 14 May 2018 at 19:40:18 UTC, 12345swordy wrote:
 A slippery slope fallacy isn't helping your case. Write a DIP 
 if it bothers you so much, as it changes the languages 
 fundamentally.


 Alexander
If 'getting a module to respect the enscapsulation boundaries the programmer puts in place would change the language so 'fundamentally', then the language 'already' presents big problems for large complex application development.
Evidence for this claim please.
- Object independence - Do not violate encapsulation - Respect the interface All large software projects are done in (or moving toward) languages that respect these idioms. Those that don't, are the ones we typically have problems with. Isn't that evidence enough? D modules provide uncontrolled violation of encapsulation (i.e can bypass the interface), and completely undermine these established idioms. D modules, will let anyone (within that module) access your wallet and take whatever they want. http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf

Again write a DIP if this bothers you. You are not going to make any language changes by ranting about it on the forums.
yeah.. I get it.. don't discuss anything, don't explore ideas or why others might think differently, just go off and write a DIP. That's why DIP's are so often poorly written and not worth the time of those that have to look at them. I think such talk is just a way to shut down the converation, to be honest. Based on this discussion so far, what I've gauged, is that spending the effort to write a dip, would be pointless (at least at this stage). If D ever takes off (and I'm not sure it will, precisely because of the way it disregards those idioms I mentioned), then more pressure will come on D to change - and perhaps then sufficient support for a DIP would be there. But I honestly don't see how it can take off, unless if first respects those idioms.
May 14 2018
next sibling parent reply Norm <norm.rowtree gmail.com> writes:
On Tuesday, 15 May 2018 at 02:32:05 UTC, KingJoffrey wrote:
 On Tuesday, 15 May 2018 at 02:00:17 UTC, 12345swordy wrote:
 On Tuesday, 15 May 2018 at 00:28:42 UTC, KingJoffrey wrote:
 On Monday, 14 May 2018 at 19:40:18 UTC, 12345swordy wrote:
 A slippery slope fallacy isn't helping your case. Write a 
 DIP if it bothers you so much, as it changes the languages 
 fundamentally.


 Alexander
If 'getting a module to respect the enscapsulation boundaries the programmer puts in place would change the language so 'fundamentally', then the language 'already' presents big problems for large complex application development.
Evidence for this claim please.
- Object independence - Do not violate encapsulation - Respect the interface All large software projects are done in (or moving toward) languages that respect these idioms. Those that don't, are the ones we typically have problems with. Isn't that evidence enough?
I'm seeing the opposite, more and more large applications adopting Python as much as possible and replacing big chunks of the C++ core and leaving only those C++ chunks where performance is all that really matters. Encapsulation boundaries are completely arbitrary and where D choses to draw the line works very well in practice. Bye, Norm
May 14 2018
parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 03:32:22 UTC, Norm wrote:
 I'm seeing the opposite, more and more large applications 
 adopting Python as much as possible and replacing big chunks of 
 the C++ core and leaving only those C++ chunks where 
 performance is all that really matters.

 Encapsulation boundaries are completely arbitrary and where D 
 choses to draw the line works very well in practice.

 Bye,
 Norm
"Encapsulation boundaries are completely arbitrary.." I love it. We have so much to look forward to, as more and more languages, and more and more quality software projects, embrace that 1950's idiom.
May 14 2018
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 15 May 2018 at 02:32:05 UTC, KingJoffrey wrote:

 - Object independence
 - Do not violate encapsulation
 - Respect the interface
This is what I don't get from your position. What is encapsulation? Here's what Wikipedia says [1]: "Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them. Publicly accessible methods are generally provided in the class (so-called getters and setters) to access the values, and other client classes call these methods to retrieve and modify the values within the object." This has been my understanding of encapsulation since I first learned of it years ago. How is this broken in D? Only if you insist on viewing it in a strictly theoretical sense. As a matter of practical reality, it is not broken. If you have access to the internals of the class, you also have access to the rest of the module. No client of the class outside of the module has any access to the implementation. I showed you an example earlier of how silly it would be to force the rest of the module to use some sort of "module private" interface. The class in D *is* encapsulated. The interface *is* respected. I'm not sure what you mean by object independence. [1] https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
May 14 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, May 15, 2018 04:22:30 Mike Parker via Digitalmars-d wrote:
 On Tuesday, 15 May 2018 at 02:32:05 UTC, KingJoffrey wrote:
 - Object independence
 - Do not violate encapsulation
 - Respect the interface
This is what I don't get from your position. What is encapsulation? Here's what Wikipedia says [1]: "Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them. Publicly accessible methods are generally provided in the class (so-called getters and setters) to access the values, and other client classes call these methods to retrieve and modify the values within the object." This has been my understanding of encapsulation since I first learned of it years ago. How is this broken in D? Only if you insist on viewing it in a strictly theoretical sense. As a matter of practical reality, it is not broken. If you have access to the internals of the class, you also have access to the rest of the module. No client of the class outside of the module has any access to the implementation. I showed you an example earlier of how silly it would be to force the rest of the module to use some sort of "module private" interface. The class in D *is* encapsulated. The interface *is* respected. I'm not sure what you mean by object independence. [1] https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
If you really insist on the viewpoint that class encapsulation means that nothing outside of that class can access any of its private members, then what D does definitely breaks encapsulation. But having friends in C++ already provides a way to break that. And having access levels like protected and package break it. Ultimately, a good language provides ways to encapsulate data and control access to the internals of a data type, but there are a variety of ways that that can be achieved, and I don't think that I've ever used a language that strictly enforces that nothing can access the internals of a class. It's just that each language provides different ways for stuff outside the class to access the class' internals. D happens to have gone with a very liberal approach to encapsulation by essentially making everything inside a module friends of each other. It doesn't break the concept of encapsulation any more than C++'s friend or Java's package attribute do. It's just a much more liberal default, and if you're really insistent that nothing outside of a class has access to the stuff inside a class, then D's choice is likely to be seem terrible. So, in that sense, I can see where he's coming from, but ultimately, I think that it's a very narrow viewpoint about what encapsulation means, and for most of us, experience has shown that D's choice works extremely well in practice. Either way, as long as you understand how D works with private, you have basically the same level of control as what you get with C++ and friend. It's just that if you _really_ don't want anything else to be a friend, you're forced to stick it in another module. So, ultimately, I think that it's mostly a theoretical debate. Pretty much the worst that happens is you accidentally use a member variable directly instead of using a property function to access it, and that's rarely a big deal. Often, it's even desirable. Regardless, I think that it's quite clear that we're not going to convince KingJoffrey of anything, and it's unlikely that he's going to convince us - though honestly, with that username, I have to wonder if he's complaining about this issue to just screw around with us for fun. But even if he's completely serious, I think that it's clear that at best we're going to agree to disagree. - Jonathan M Davis
May 14 2018
next sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 04:46:18 UTC, Jonathan M Davis wrote:
 If you really insist on the viewpoint that class encapsulation 
 means that nothing outside of that class can access any of its 
 private members, then what D does definitely breaks 
 encapsulation. But having friends in C++ already provides a way 
 to break that.
No. That is not true. friend is explicately part of the declared interface. D on the otherhand, tells you who your friends are. Your interface doesn't have a say in it anymore. When your declared interface is moot, your enscapsulation is also moot.
 Regardless, I think that it's quite clear that we're not going 
 to convince KingJoffrey of anything, and it's unlikely that 
 he's going to convince us - though honestly, with that 
 username, I have to wonder if he's complaining about this issue 
 to just screw around with us for fun. But even if he's 
 completely serious, I think that it's clear that at best we're 
 going to agree to disagree.

 - Jonathan M Davis
I prefer to think of it as a discussion. Even though I'm right ;-) But in any case, i feel I've presented some worthwhile arguements. The only arguments I've got so far from the other point of view, is that's how D does it. If you don't like it, go wrute a DIP.
May 14 2018
prev sibling next sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 04:46:18 UTC, Jonathan M Davis wrote:
 Pretty much the worst that happens is you accidentally use a 
 member variable directly instead of using a property function 
 to access it, and that's rarely a big deal. Often, it's even 
 desirable.
I'll keep that argument for the status quo, and will be sure to put it in the DIP.
May 14 2018
prev sibling parent reply aliak <something something.com> writes:
On Tuesday, 15 May 2018 at 04:46:18 UTC, Jonathan M Davis wrote:
 On Tuesday, May 15, 2018 04:22:30 Mike Parker via Digitalmars-d 
 wrote:
 On Tuesday, 15 May 2018 at 02:32:05 UTC, KingJoffrey wrote:
 - Object independence
 - Do not violate encapsulation
 - Respect the interface
This is what I don't get from your position. What is encapsulation? Here's what Wikipedia says [1]:
[...]
 The class in D *is* encapsulated. The interface *is* 
 respected. I'm not sure what you mean by object independence.


 [1]
 https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
If you really insist on the viewpoint that class encapsulation means that nothing outside of that class can access any of its private members, then what D does definitely breaks encapsulation. But having friends in C++ already provides a way to break that. And having access levels like protected and package break it. Ultimately, a good language provides ways to encapsulate data and control access to the internals of a data type, but there are a variety of ways that that can be achieved, and I don't think that I've ever used a language that strictly enforces that nothing can access the internals of a class. It's just that each language provides different ways for stuff outside the class to access the class' internals. D happens to have gone with a very liberal approach to encapsulation by essentially making everything inside a module friends of each other. It doesn't break the concept of encapsulation any more than C++'s friend or Java's package attribute do. It's just a much more liberal default, and if you're really insistent that nothing outside of a class has access to the stuff inside a class, then D's choice is likely to be seem terrible. So, in that sense, I can see where he's coming from, but ultimately, I think that it's a very narrow viewpoint about what encapsulation means, and for most of us, experience has shown that D's choice works extremely well in practice. Either way, as long as you understand how D works with private, you have basically the same level of control as what you get with C++ and friend. It's just that if you _really_ don't want anything else to be a friend, you're forced to stick it in another module. So, ultimately, I think that it's mostly a theoretical debate. Pretty much the worst that happens is you accidentally use a member variable directly instead of using a property function to access it, and that's rarely a big deal. Often, it's even desirable.
[...]
 - Jonathan M Davis
With one big difference, in that those other languages make you explicitly leak object internals, if you want it, and also allow you to maintain it, if you want it, whereas D implicitly leaks class privates to the module whether you want it or not. So private in a class is nonintuitive and does indeed break encapsulation. This is why Swift has fileprivate to distinguish this case, and for good reason. So I understand D wants to be liberal, but I also understand the value of "encapsulation where I want encapsulation to happen", which D doesn't let me do without jumping through extra hoops (extracting class to another module with the caveat that you lose first-class UFCS enabled function access), and only after I've spent hours trying to track a state-related bug because private is not scoped at the declaration level. Cheers - Ali
May 15 2018
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Tuesday, 15 May 2018 at 12:20:34 UTC, aliak wrote:
 On Tuesday, 15 May 2018 at 04:46:18 UTC, Jonathan M Davis wrote:
 On Tuesday, May 15, 2018 04:22:30 Mike Parker via 
 Digitalmars-d wrote:
 On Tuesday, 15 May 2018 at 02:32:05 UTC, KingJoffrey wrote:
 - Object independence
 - Do not violate encapsulation
 - Respect the interface
This is what I don't get from your position. What is encapsulation? Here's what Wikipedia says [1]:
[...]
 The class in D *is* encapsulated. The interface *is* 
 respected. I'm not sure what you mean by object independence.


 [1]
 https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
If you really insist on the viewpoint that class encapsulation means that nothing outside of that class can access any of its private members, then what D does definitely breaks encapsulation. But having friends in C++ already provides a way to break that. And having access levels like protected and package break it. Ultimately, a good language provides ways to encapsulate data and control access to the internals of a data type, but there are a variety of ways that that can be achieved, and I don't think that I've ever used a language that strictly enforces that nothing can access the internals of a class. It's just that each language provides different ways for stuff outside the class to access the class' internals. D happens to have gone with a very liberal approach to encapsulation by essentially making everything inside a module friends of each other. It doesn't break the concept of encapsulation any more than C++'s friend or Java's package attribute do. It's just a much more liberal default, and if you're really insistent that nothing outside of a class has access to the stuff inside a class, then D's choice is likely to be seem terrible. So, in that sense, I can see where he's coming from, but ultimately, I think that it's a very narrow viewpoint about what encapsulation means, and for most of us, experience has shown that D's choice works extremely well in practice. Either way, as long as you understand how D works with private, you have basically the same level of control as what you get with C++ and friend. It's just that if you _really_ don't want anything else to be a friend, you're forced to stick it in another module. So, ultimately, I think that it's mostly a theoretical debate. Pretty much the worst that happens is you accidentally use a member variable directly instead of using a property function to access it, and that's rarely a big deal. Often, it's even desirable.
[...]
 - Jonathan M Davis
With one big difference, in that those other languages make you explicitly leak object internals, if you want it, and also allow you to maintain it, if you want it, whereas D implicitly leaks class privates to the module whether you want it or not. So private in a class is nonintuitive and does indeed break encapsulation. This is why Swift has fileprivate to distinguish this case, and for good reason. So I understand D wants to be liberal, but I also understand the value of "encapsulation where I want encapsulation to happen", which D doesn't let me do without jumping through extra hoops (extracting class to another module with the caveat that you lose first-class UFCS enabled function access), and only after I've spent hours trying to track a state-related bug because private is not scoped at the declaration level. Cheers - Ali
The way you use the word "leak" make is sounds that this is unintentional, while in reality it is intentional by design. That why reading the specification is important! Alexander
May 15 2018
parent reply aliak <something something.com> writes:
On Tuesday, 15 May 2018 at 13:16:55 UTC, 12345swordy wrote:
 The way you use the word "leak" make is sounds that this is 
 unintentional, while in reality it is intentional by design. 
 That why reading the specification is important!

 Alexander
Ya I guess you be right - but a leak is what it is to people who expect private to mean private. Which is not a small number of people ;) And while I agree reading a spec is important. Language specs are not known for being trivial to go through and it's not really something you read but more of something you refer to, and that also probably for more advanced developers. This is not something you can expect newcomers or even intermediate level devs to go through. And the less you need to refer to a spec the better (i.e. more intuitive) a language is.
May 15 2018
parent reply Dlang User <dlang.user gmx.com> writes:
On 5/15/2018 10:17 AM, aliak wrote:
 On Tuesday, 15 May 2018 at 13:16:55 UTC, 12345swordy wrote:
 The way you use the word "leak" make is sounds that this is 
 unintentional, while in reality it is intentional by design. That why 
 reading the specification is important!

 Alexander
Ya I guess you be right - but a leak is what it is to people who expect private to mean private. Which is not a small number of people ;) And while I agree reading a spec is important. Language specs are not known for being trivial to go through and it's not really something you read but more of something you refer to, and that also probably for more advanced developers. This is not something you can expect newcomers or even intermediate level devs to go through. And the less you need to refer to a spec the better (i.e. more intuitive) a language is.
background), I figured that I already knew all of the OOP stuff and didn't dig too deeply into it, figuring that it worked pretty close to really worked in D. But the work around (putting it in its own module), didn't bother me too much.
May 15 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, May 15, 2018 12:21:23 Dlang User via Digitalmars-d wrote:
 On 5/15/2018 10:17 AM, aliak wrote:
 On Tuesday, 15 May 2018 at 13:16:55 UTC, 12345swordy wrote:
 The way you use the word "leak" make is sounds that this is
 unintentional, while in reality it is intentional by design. That why
 reading the specification is important!

 Alexander
Ya I guess you be right - but a leak is what it is to people who expect private to mean private. Which is not a small number of people ;) And while I agree reading a spec is important. Language specs are not known for being trivial to go through and it's not really something you read but more of something you refer to, and that also probably for more advanced developers. This is not something you can expect newcomers or even intermediate level devs to go through. And the less you need to refer to a spec the better (i.e. more intuitive) a language is.
background), I figured that I already knew all of the OOP stuff and didn't dig too deeply into it, figuring that it worked pretty close to really worked in D. But the work around (putting it in its own module), didn't bother me too much.
I think that if there's an actual problem here, it's the fact that how private works in D is surprising to folks coming from languages like C++, understand what it is, you risk problems, just like with any other feature that you don't understand properly. And to better deal with that, we probably need more in the way of documentation geared towards teaching newbies. The "spec" is pretty poor in that it's not precise enough to be a spec, meaning that it doesn't really do its job in that respect, but it's also not really written with the idea that it's teaching someone, so it doesn't do a great job teaching the language either. There's a lot of great information there, but it's ultimately not all that accessible for many folks. Though if someone expects to be able to just jump into any language and use it without reading up on how it works, they're just shooting themselves in the foot. And surprisingly often, that seems to be how many folks operate. Ultimately, if newcomers don't want to be tripped up on stuff like this, their best bet is probably to read books like Andrei's "The D Programming Language" and Ali's "Programming in D." https://wiki.dlang.org/Books - Jonathan M Davis
May 15 2018
next sibling parent Neia Neutuladh <neia ikeran.org> writes:
On Tuesday, 15 May 2018 at 21:05:10 UTC, Jonathan M Davis wrote:
 Though if someone expects to be able to just jump into any 
 language and use it without reading up on how it works, they're 
 just shooting themselves in the foot. And surprisingly often, 
 that seems to be how many folks operate.
It works pretty well because programming languages tend to be Knowing C++ and a bit of lore, you can transition to Java pretty instance, or to OCaml, or METAFONT. You might be surprised that some things are missing. You might not know about some things that would help you. You might be writing code inefficiently, and you will likely write code that's not idiomatic, that's hard for others to read. But you can still get things done. And then you encounter things that break, and you look for other ways of doing that. D's protection attributes are not that different from Java's, so things look the same at first. And when they're different, they differ in a hard-to-spot way. There isn't much cure for this.
May 15 2018
prev sibling next sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 21:05:10 UTC, Jonathan M Davis wrote:
 Ultimately, if newcomers don't want to be tripped up on stuff 
 like this, their best bet is probably to read books like 
 Andrei's "The D Programming Language" and Ali's "Programming in 
 D."
"The unit of object encapsulation in D is the class." - page 175, The D Programming Language, 2010, Andrei Alexandrescu. What it really should have included, locally, within that same section, is the implications of this 'encapsulation' with regards to how 'facebook like friendship' is a core design component of the D module. i.e, on the next line, Andrei could have continued.. "However, if your class is contained within a module, then this encapsulation barrier kinda breaks down, because everything in the module becomes a friend of that class, whether you like it or not. You have no say in the matter. If you don't like it, fine, but that's how D does things, so just be careful what you put in a module".
May 15 2018
parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 02:15:45 UTC, KingJoffrey wrote:
 "The unit of object encapsulation in D is the class." - page 
 175, The D Programming Language, 2010, Andrei Alexandrescu.

 What it really should have included, locally, within that same 
 section, is the implications of this 'encapsulation' with 
 regards to how 'facebook like friendship' is a core design 
 component of the D module.

 i.e, on the next line, Andrei could have continued..

 "However, if your class is contained within a module, then this 
 encapsulation barrier kinda breaks down, because everything in 
 the module becomes a friend of that class, whether you like it 
 or not. You have no say in the matter. If you don't like it, 
 fine, but that's how D does things, so just be careful what you 
 put in a module".
Although, to be fair to Andrei, once you get to page 200 (25 pages after the above comment about class encapsulation), you do, finally, get some clarification: "In all contexts, private has the same power: it restricts symbol access to the current module (file). This behavior is unlike that in other languages, which limit access to private symbols to the current class only. ... If class-level protection is needed, simply put the class in its own file."
May 15 2018
prev sibling next sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 21:05:10 UTC, Jonathan M Davis wrote:
 Though if someone expects to be able to just jump into any 
 language and use it without reading up on how it works, they're 
 just shooting themselves in the foot. And surprisingly often, 
 that seems to be how many folks operate.
And that comment is a little unfair don't you think? The best clarification I can find, regarding how D treat's private, is from this tiny little sentence (from which, I assume, the programmer is now meant to understand it's full implications): "Symbols with private visibility can only be accessed from within the same module" https://dlang.org/spec/attribute.html#visibility_attributes
May 15 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, May 16, 2018 02:39:22 KingJoffrey via Digitalmars-d wrote:
 On Tuesday, 15 May 2018 at 21:05:10 UTC, Jonathan M Davis wrote:
 Though if someone expects to be able to just jump into any
 language and use it without reading up on how it works, they're
 just shooting themselves in the foot. And surprisingly often,
 that seems to be how many folks operate.
And that comment is a little unfair don't you think?
Is it? How many programmers just start trying to program in D without actually reading much of anything about it? We not only have the spec but multiple books on the language - some of which are available for free - and yet plenty of programmers (regardless of the language) seem to think that they can just start programming in a language and only look up stuff when they run into a problem and yet expect to have that work well without running into serious problems. Anyone taking that approach is just begging for trouble. Obviously, not everyone does that, but a suprisingly large number of programmers seem to. We try to help such folks when they do ask questions, but plenty of questions that get asked clearly show that the person asking the question has not studied the language much at all.
 The best clarification I can find, regarding how D treat's
 private, is from this tiny little sentence (from which, I assume,
 the programmer is now meant to understand it's full implications):

 "Symbols with private visibility can only be accessed from within
 the same module"

 https://dlang.org/spec/attribute.html#visibility_attributes
It specifies what private does quite accurately. If you want something that's trying to point out how you might misunderstand the spec or what problems you might run into, you'll need to read something like Ali's book. The spec is telling you how the language works, not trying to tell you how you might misunderstand it or what misakes you might make. And the information it gives there is quite accurate and complete. Honestly, I would have thought that knowing that private is private to the module would be plenty to understand what that then means for structs or classes, but everyone thinks differently and absorbs or misses different pieces of information. But ultimately, anyone who doesn't understand something is free to ask in places like D.Learn or stackoverflow. - Jonathan M Davis
May 15 2018
next sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 03:12:03 UTC, Jonathan M Davis wrote:
 It specifies what private does quite accurately. If you want 
 something that's trying to point out how you might 
 misunderstand the spec or what problems you might run into, 
 you'll need to read something like Ali's book. The spec is 
 telling you how the language works, not trying to tell you how 
 you might misunderstand it or what misakes you might make. And 
 the information it gives there is quite accurate and complete. 
 Honestly, I would have thought that knowing that private is 
 private to the module would be plenty to understand what that 
 then means for structs or classes, but everyone thinks 
 differently and absorbs or misses different pieces of 
 information. But ultimately, anyone who doesn't understand 
 something is free to ask in places like D.Learn or 
 stackoverflow.

 - Jonathan M Davis
To suggest that "Symbols with private visibility can only be accessed from within the same module" - is all you need to know (if you're lucky to find the needle in the haystack), is kinda elitist. People expect norms to be the norm. That's entirely reasonable. If I see a STOP sign while I'm driving, I expect it means STOP, not 'STOP..if.." If I see private, I expect it means private, not 'private..if'. The language reference could, and should do better.
May 15 2018
next sibling parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Wednesday, 16 May 2018 at 03:36:39 UTC, KingJoffrey wrote:
 On Wednesday, 16 May 2018 at 03:12:03 UTC, Jonathan M Davis 
 wrote:
 [...]
 - Jonathan M Davis
To suggest that "Symbols with private visibility can only be accessed from within the same module" - is all you need to know (if you're lucky to find the needle in the haystack), is kinda elitist.
One is expected to know the tool they are using. There is nothing elitist about that.
 People expect norms to be the norm. That's entirely reasonable.

 If I see a STOP sign while I'm driving, I expect it means STOP, 
 not 'STOP..if.."

 If I see private, I expect it means private, not 'private..if'.
There is no if. You know what the stop sign means because someone told you what it means. private means it is only available to the module. It is entirely the fault of the user for not reading the docs.
 The language reference could, and should do better.
Its actively being improved, but in this case it was more than adequate. The spec was pretty clear that private applies to modules.
May 15 2018
parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 03:52:43 UTC, Uknown wrote:
 One is expected to know the tool they are using. There is 
 nothing elitist about that.
That is a pathetic, and yet another elitist view. If programmers never programmed until they 'understood the tool', there would not be 20+ million programmers in the world. How many C++ programmers understand C++ (let alone have read the spec). The same can be asked for pretty much any other language. Learning is still a gradual process - except for elitists it seems, who expect you to know everything up front.
 There is no if. You know what the stop sign means because 
 someone told you what it means. private means it is only 
 available to the module. It is entirely the fault of the user 
 for not reading the docs.
Another elitist view.
 Its actively being improved, but in this case it was more than 
 adequate. The spec was pretty clear that private applies to 
 modules.
I disagree.
May 15 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, May 16, 2018 03:36:39 KingJoffrey via Digitalmars-d wrote:
 On Wednesday, 16 May 2018 at 03:12:03 UTC, Jonathan M Davis wrote:
 It specifies what private does quite accurately. If you want
 something that's trying to point out how you might
 misunderstand the spec or what problems you might run into,
 you'll need to read something like Ali's book. The spec is
 telling you how the language works, not trying to tell you how
 you might misunderstand it or what misakes you might make. And
 the information it gives there is quite accurate and complete.
 Honestly, I would have thought that knowing that private is
 private to the module would be plenty to understand what that
 then means for structs or classes, but everyone thinks
 differently and absorbs or misses different pieces of
 information. But ultimately, anyone who doesn't understand
 something is free to ask in places like D.Learn or
 stackoverflow.

 - Jonathan M Davis
To suggest that "Symbols with private visibility can only be accessed from within the same module" - is all you need to know (if you're lucky to find the needle in the haystack), is kinda elitist. People expect norms to be the norm. That's entirely reasonable. If I see a STOP sign while I'm driving, I expect it means STOP, not 'STOP..if.." If I see private, I expect it means private, not 'private..if'.
I don't see why it would be elitist to expect folks to read the spec and assume that it means what it says. It's always a risk that someone is going to assume that a language that they're learning works the same way as a language that they know even if it doesn't, but anyone learning a new language needs to take into account the fact that every language works differently, and you need to read up on how the language you're learning actually works if you want to avoid misunderstanding stuff. private is far from the only feature in D that doesn't work quite like it does in other languages.
 The language reference could, and should do better.
I think that really what you want is something that's geared more towards teaching the language. The ways that the language spec needs to be improved really revolve around making it a proper spec, which means making it far more precise, not making it more amenable to folks reading it in order to learn the language. But unfortunately, what we have right now is kind of in the middle. It's not precise enough to really be a proper spec, and it's generally terse enough that it's harder to use it as a learning resource (though it usually has the necessary information in it). - Jonathan M Davis
May 15 2018
next sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 04:25:40 UTC, Jonathan M Davis wrote:
 The ways that the language spec needs to be improved really 
 revolve around making it a proper spec, which means making it 
 far more precise, not making it more amenable to folks reading 
 it in order to learn the language.
I love it. I'll add that to my list of 'D forum qoutes'.
May 15 2018
prev sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 04:25:40 UTC, Jonathan M Davis wrote:
 I think that really what you want is something that's geared 
 more towards teaching the language. The ways that the language 
 spec needs to be improved really revolve around making it a 
 proper spec, which means making it far more precise, not making 
 it more amenable to folks reading it in order to learn the 
 language. But unfortunately, what we have right now is kind of 
 in the middle. It's not precise enough to really be a proper 
 spec, and it's generally terse enough that it's harder to use 
 it as a learning resource (though it usually has the necessary 
 information in it).

 - Jonathan M Davis
Also, having a C++ like spec, written by the elite, for the elite, and then everyone else has to wait until some kind person explains the spec, is really not a great model. It's equivalent to the elitist view of trickle down economics - which is not working in my country.
May 15 2018
next sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 05:43:58 UTC, KingJoffrey wrote:
 Also, having a C++ like spec, written by the elite, for the 
 elite, and then everyone else has to wait until some kind 
 person explains the spec, is really not a great model.

 It's equivalent to the elitist view of trickle down economics - 
 which is not working in my country.
oh, and btw, even the elite don't truly understand the tool. they, they like all people, understand bit and pieces of this and that, some bits more than others, some less than others. Please find me the number of C++ programmers who understand C++. https://www.youtube.com/watch?v=YAP_xTsapW0
May 15 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, May 16, 2018 05:43:58 KingJoffrey via Digitalmars-d wrote:
 On Wednesday, 16 May 2018 at 04:25:40 UTC, Jonathan M Davis wrote:
 I think that really what you want is something that's geared
 more towards teaching the language. The ways that the language
 spec needs to be improved really revolve around making it a
 proper spec, which means making it far more precise, not making
 it more amenable to folks reading it in order to learn the
 language. But unfortunately, what we have right now is kind of
 in the middle. It's not precise enough to really be a proper
 spec, and it's generally terse enough that it's harder to use
 it as a learning resource (though it usually has the necessary
 information in it).

 - Jonathan M Davis
Also, having a C++ like spec, written by the elite, for the elite, and then everyone else has to wait until some kind person explains the spec, is really not a great model. It's equivalent to the elitist view of trickle down economics - which is not working in my country.
A C++-like spec is exactly what a language specification should be. It's intended for folks like compiler writers so that they know the exact rules of the language in excruciating detail so that every implementation can match in the ways that they need to match (as well as making it so that the compiler writer knows where they have leeway). D's spec is very poor in that regard, largely because writing specs is not one of Walter Bright's strengths (something that he has freely admitted on several occasions). However, Andrei has made it a priority to improve D's spec so that it is detailed in the way that the C++ spec is. So, we should see movement towards having a spec more like what C++ has. Part of the problem with D's spec is that it's basically both trying to be a specification for the language and be a way to explain the language to the typical programmer, and those aren't really compatible goals. We really need to have anything intended to teach the language be separate from the spec, but historically, the main resource that we've had is the spec. Fortunately however, the number of books that we have about D has been increasing, and for many programmers, those are going to be better tools for learning the language. - Jonathan M Davis
May 16 2018
parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 10:24:02 UTC, Jonathan M Davis wrote:
 Part of the problem with D's spec is that it's basically both 
 trying to be a specification for the language and be a way to 
 explain the language to the typical programmer, and those 
 aren't really compatible goals. We really need to have anything 
 intended to teach the language be separate from the spec..
The specification (the one available above under 'Documentation', can be simply be 'annotated', and therefore serve more that just 'folks like compiler writers'. Those who don't need the annotations, can just ignore the annotations. I'm not talking 'tutorials' here, just some extra, helpful explanation. al) is still one of my favourite all time books (because of the mix of specification and expert annotations).
May 16 2018
prev sibling parent reply meppl <mephisto nordhoff-online.de> writes:
On Wednesday, 16 May 2018 at 03:12:03 UTC, Jonathan M Davis wrote:
 On Wednesday, May 16, 2018 02:39:22 KingJoffrey via 
 Digitalmars-d wrote:
 On Tuesday, 15 May 2018 at 21:05:10 UTC, Jonathan M Davis 
 wrote:
 ...
...
 The best clarification I can find, regarding how D treat's 
 private, is from this tiny little sentence (from which, I 
 assume, the programmer is now meant to understand it's full 
 implications):

 "Symbols with private visibility can only be accessed from 
 within the same module"

 https://dlang.org/spec/attribute.html#visibility_attributes
It specifies what private does quite accurately. If you want something that's trying to point out how you might misunderstand the spec or what problems you might run into, you'll need to read something like Ali's book. The spec is telling you how the language works, not trying to tell you how you might misunderstand it or what misakes you might make.
...
 - Jonathan M Davis
a pitfall-section about 'private' and 'protected' in https://dlang.org/spec/class.html wouldnt hurt. KingJoffrey is not the first one at all who discovered this corner case _afterwards_. I saw it in the forum. Additionally I am curious about the "you must read a book"-statement, if KingJoffrey learned almost anything by reading the specification-documentation except for a few pitfalls.
May 16 2018
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 05/16/2018 04:28 AM, meppl wrote:
 a pitfall-section about 'private' and 'protected' in 
 https://dlang.org/spec/class.html wouldnt hurt.
Yah, improvements to the spec are always welcome and not difficult to effect. It's one of the areas in which crowdsourcing would work nicely.
May 16 2018
prev sibling next sibling parent dlang user <dlang.user gmx.com> writes:
On 05/15/2018 04:05 PM, Jonathan M Davis wrote:
 On Tuesday, May 15, 2018 12:21:23 Dlang User via Digitalmars-d wrote:
 On 5/15/2018 10:17 AM, aliak wrote:
 On Tuesday, 15 May 2018 at 13:16:55 UTC, 12345swordy wrote:
 The way you use the word "leak" make is sounds that this is
 unintentional, while in reality it is intentional by design. That why
 reading the specification is important!

 Alexander
Ya I guess you be right - but a leak is what it is to people who expect private to mean private. Which is not a small number of people ;) And while I agree reading a spec is important. Language specs are not known for being trivial to go through and it's not really something you read but more of something you refer to, and that also probably for more advanced developers. This is not something you can expect newcomers or even intermediate level devs to go through. And the less you need to refer to a spec the better (i.e. more intuitive) a language is.
background), I figured that I already knew all of the OOP stuff and didn't dig too deeply into it, figuring that it worked pretty close to really worked in D. But the work around (putting it in its own module), didn't bother me too much.
I think that if there's an actual problem here, it's the fact that how private works in D is surprising to folks coming from languages like C++, understand what it is, you risk problems, just like with any other feature that you don't understand properly. And to better deal with that, we probably need more in the way of documentation geared towards teaching newbies. The "spec" is pretty poor in that it's not precise enough to be a spec, meaning that it doesn't really do its job in that respect, but it's also not really written with the idea that it's teaching someone, so it doesn't do a great job teaching the language either. There's a lot of great information there, but it's ultimately not all that accessible for many folks. Though if someone expects to be able to just jump into any language and use it without reading up on how it works, they're just shooting themselves in the foot. And surprisingly often, that seems to be how many folks operate. Ultimately, if newcomers don't want to be tripped up on stuff like this, their best bet is probably to read books like Andrei's "The D Programming Language" and Ali's "Programming in D." https://wiki.dlang.org/Books - Jonathan M Davis
To clarify myself a little bit, the main points that I was agreeing with were: 1. I think there are significant number of people coming from other languages that are going to get tripped up by D's module level encapsulation, mainly because it happened to me. 2. The spec is hard to use as a training resource, because I tried to use it and didn't have a good experience with it. I ended up reading all of the free material that I could find (including the Programming in D book). I also wasn't trying say anything about D's encapsulation being right or wrong, just that it tripped me up initially, and that now that I know how it works, it isn't a big deal for me.
May 15 2018
prev sibling parent bachmeier <no spam.net> writes:
On Tuesday, 15 May 2018 at 21:05:10 UTC, Jonathan M Davis wrote:

 Ultimately, if newcomers don't want to be tripped up on stuff 
 like this, their best bet is probably to read books like 
 Andrei's "The D Programming Language" and Ali's "Programming in 
 D."
The wiki has a section dedicated to discussion of these matters for newcomers from other languages. https://wiki.dlang.org/Coming_From#Specific_Language I don't know how many newcomers are aware of that information, but that's really the place for it.
May 16 2018
prev sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 04:22:30 UTC, Mike Parker wrote:
 On Tuesday, 15 May 2018 at 02:32:05 UTC, KingJoffrey wrote:

 - Object independence
 - Do not violate encapsulation
 - Respect the interface
This is what I don't get from your position. What is encapsulation? Here's what Wikipedia says [1]: "Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them. Publicly accessible methods are generally provided in the class (so-called getters and setters) to access the values, and other client classes call these methods to retrieve and modify the values within the object." This has been my understanding of encapsulation since I first learned of it years ago. How is this broken in D? Only if you insist on viewing it in a strictly theoretical sense. As a matter of practical reality, it is not broken. If you have access to the internals of the class, you also have access to the rest of the module. No client of the class outside of the module has any access to the implementation. I showed you an example earlier of how silly it would be to force the rest of the module to use some sort of "module private" interface. The class in D *is* encapsulated. The interface *is* respected. I'm not sure what you mean by object independence. [1] https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
Yes, it's a vague word which can be interpreted different ways. I primarily mean the more abstract notion of 'boundaries' and 'interfaces'. The concept is well presented in this keynote at ACCU 2018: https://www.youtube.com/watch?v=IP5akjPwqEA E.g. passing from one room to another, via a door. The door presents the boundary, and the interface through which you access each room. You cannot go star trek style (yet) and just beam from one room to the other. 'Beam me up scotty' is just for the movies (as far as I know ;-) Also, if there is no boundary between the orange room and the blue room, how would I get from the orange room to the blue room - or vica versa? The only reality our brains can perceive, is the reality made of from boundaries and interfaces. We cannot hold all of reality in our head. We have to break things down into little self-contained chunks, and then understand how the chunks connect together. It becomes particularly important when trying to understand complexity (of any kind). 943294432432812 // grr! 943_294_432_432_812 // nice the underscore represent the boundary. the information between boundaries is now encapsulated (because of that boundary) Now, back to D... in this example code below, the D module does not respect the boundary of the object. That is, the module can beam into the object without going through the interface. I struggle to understand why the module is allowed to do this - I really cannot get my head around any valid reason for it - I'm just getting told, 'that's how D does it' -or - 'it doesn't really bother us'. If I cannot control the interface, and have that respected by the module, then this allows the kind of bugs that actually lead me to working out that private is not really private at all. as I know, Rust and Go. They would have all respected the boundary. D has chosen to allow the module to disrespect the interface. Why? (and don't tell me it does - cause the code below clearly demonstrates that it does not) ======= module test; void foo() { Person p = new Person("King Joffrey"); // this completely bypasses my interface // (i.e. the boundary that I set up between the class and the module) p._name = "New King"; } class Person { private string _name; public void setName(string name) { this._name = name; } public this(string name) { _name = name; } } ================================
May 14 2018
parent reply Mike Parker <aldacron gmail.com> writes:
 (and don't tell me it does - cause the code below clearly 
 demonstrates that it does not)

 =======
 module test;

 void foo()
 {
     Person p = new Person("King Joffrey");

     // this completely bypasses my interface
     // (i.e. the boundary that I set up between the class and 
 the module)
     p._name = "New King";

 }

 class Person
 {
     private string _name;

     public void setName(string name)
     {
         this._name = name;
     }

     public this(string name)
     {
         _name = name;
     }

 }

 ================================
Jonathan's right. We're just not going to agree on this. The implementation is still encapsulated behind the public interface. If you don't want main to access Person's private members, then don't put them in the same module. Period. Modules are a cohesive unit, not simply a means of grouping related constructs. If the latter is all you're using them for, then the solution is simple. Given the following: module foo.bar.baz; class A {} class B {} class C {} void funca() {} void funcb() {} You can keep your grouping and get your strict encapsulation like so: // foo/bar/baz/package.d module foo.bar.baz; public import foo.bar.baz.a, foo.bar.baz.b, foo.bar.baz.c, foo.bar.baz.funcs; The client need neither know nor care that everything is in separate modules and you get your strict encapsulation. You can still share items between modules via package protection, and within specific package hierarchies via package(packageName). And even better, you now have less code per module to reason about (re: one of your earlier arguments against the current behavior).
May 14 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 05:59:44 UTC, Mike Parker wrote:
 Jonathan's right. We're just not going to agree on this.
The purpose of discussion is not necessarly to get one side to agree with other side.
 You can keep your grouping and get your strict encapsulation 
 like so:

 // foo/bar/baz/package.d
 module foo.bar.baz;
 public import
     foo.bar.baz.a,
     foo.bar.baz.b,
     foo.bar.baz.c,
     foo.bar.baz.funcs;

 The client need neither know nor care that everything is in 
 separate modules and you get your strict encapsulation. You can 
 still share items between modules via package protection, and 
 within specific package hierarchies via package(packageName). 
 And even better, you now have less code per module to reason 
 about (re: one of your earlier arguments against the current 
 behavior).
Fine. If I take your solution above, and ensure that every class, goes into it's own module, and that a module containing a class, contains nothing other than a single class (i.e no free - i.e a good place, where I feel comfortable. My declared interface is respected. Why do I need D then? i.e. under what circumstances, would I want to put something extra into the module, so that it can abuse the declared interface of my class? Can you give me some examples?
May 14 2018
next sibling parent Dukc <ajieskola gmail.com> writes:
On Tuesday, 15 May 2018 at 06:38:04 UTC, KingJoffrey wrote:
 Can you give me some examples?
Defining a Voldemort type (meaning, one whose name is not public) with private members for use by multiple functions: ------- module two_functions; private struct MyForwardRange { private int function(int[]) cumulator; int[] front; void popFront() { front ~= cumulator(front); } enum empty = false; auto save() { return this; } } auto accumulate(int a, int b) { import std.algorithm; return MyForwardRange(arr => arr.sum, [a, b]); } auto extendByIota(int[] startElems) { return MyForwardRange(arr => arr.length, startElems); } ------- In a simple module like this, it would be needless complexity to make cumulator have a package visibility and put the functions in a different module. That's what you would have to do if private meant private to class, not to module.
May 15 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, May 15, 2018 06:38:04 KingJoffrey via Digitalmars-d wrote:
 On Tuesday, 15 May 2018 at 05:59:44 UTC, Mike Parker wrote:
 You can keep your grouping and get your strict encapsulation
 like so:

 // foo/bar/baz/package.d
 module foo.bar.baz;
 public import

     foo.bar.baz.a,
     foo.bar.baz.b,
     foo.bar.baz.c,
     foo.bar.baz.funcs;

 The client need neither know nor care that everything is in
 separate modules and you get your strict encapsulation. You can
 still share items between modules via package protection, and
 within specific package hierarchies via package(packageName).
 And even better, you now have less code per module to reason
 about (re: one of your earlier arguments against the current
 behavior).
Fine. If I take your solution above, and ensure that every class, goes into it's own module, and that a module containing a class, contains nothing other than a single class (i.e no free - i.e a good place, where I feel comfortable. My declared interface is respected. Why do I need D then?
I honestly don't see how D deals with private should be a major factor in deciding what language to use. Even if you see how D handles private to be negative, if its other features aren't appealing enough to make you want to use it in spite of what's going on with private, I don't see why what happens with private matters. And even if private worked the way you want it to, I don't see why that would make anyone want to use the language over C++ or Java or whatnot. How stuff like private, package, and friends are dealt with certainly has an impact on a language, but it's just one piece of many, and I would expect most people to think that it was a relatively small piece of the puzzle such that it would not be a major deciding factor in whether they use the language, whether they like what was done with access levels or not.
 i.e. under what circumstances, would I want
 to put something extra into the module, so that it can abuse the
 declared interface of my class?
The declared interface to your class is what's presented to everything outside of your module. Everything inside the module has full access just like any friend would in C++. That's basically how you have to think about it. As long as you insist that the class itself is the barrier, then you're never going to be anything but unhappy with D's approach.
 Can you give me some examples?
The prime one is unit tests. The fact that they can access the private variables is invaluable for testing the state of an object. In C++, I have always have to make all of the tests friends of the class so that they can access the internals for testing. In D, I don't have to worry about any of that, and the tests don't affect the public interface of the class at all. Also, there are plenty of cases where it's nice to be able to have private functions which can access the internals of a class - and you don't necessarily want them to be members of the class. This is particularly true when the class is templated. e.g. dxml provides a fairly simply public API in dxml.parser, but it has lots of private helper functions which access the members of the struct. They operate on stuff that isn't supposed to be publicly available, and it's cleaner to have them outside the struct where they can be tested separately from the struct. Also, why would I necessarily care if something else in the same module can access the private members of a struct or class? If they're associated closely enough to be put in the same module, then there's frequently no reason to care if they access the private members or not, and as long as you're dealing with stuff like getters and setters, unless they're doing extra work other than simply encapsulating access to a member variable, there really isn't a reason why it would be a problem for other stuff in the module to access the member variable directly. Everything in the module goes together, and you can easily change anything in there if you need to due to something changing in the internals of the struct or class, and it won't affect the public API. Everything in the module is internal. Particularly when you're talking about private functions, whether something is in the class itself or in the module is an implementation detail and largely irrelevant. And if you have a public free function that can access the class' internals, well that function is associated with the class by being in the same module just like a friend function would be, and you get all of the benefits that you'd get with a friend function without having to explicitly declare everything as friends. So, all of the same reasoning as to why you'd want a friend function applies to why it can be valuable to have something in the same module access the internals of a class. The only cost is that you can't declare something not to be a friend and have it be in the same module, and you can't declare it to be a friend when it's in another module (though package does provide similar functionality). The assumption is that anything that goes in the same module can either reasonably be treated as friends, or it doesn't matter if they are. Basically all of the same arguments that you're giving against having everything in the module being treated as friends of each other can be given against having friends in the first place. It's just that D makes it implicit within the module. - Jonathan M Davis
May 15 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 07:23:55 UTC, Jonathan M Davis wrote:
 The prime one is unit tests. The fact that they can access the 
 private variables is invaluable for testing the state of an 
 object. In C++, I have always have to make all of the tests 
 friends of the class so that they can access the internals for 
 testing. In D, I don't have to worry about any of that, and the 
 tests don't affect the public interface of the class at all.
ok. so the 'for' side arguments, for embracing Facebook style friendship in D: - Voldemort types (cause yeah...we all use them so often). - Unit tests (dare I the same ;-) Actually, I kinda get it for unit tests. Surely there's more??
 The assumption is that anything that goes in the same module 
 can either reasonably be treated as friends, or it doesn't 
 matter if they are.
Well, we already know what disasters can occur from facebook style friendships. My own code in D had bugs, cause I didn't realise all my private parts were not just visible, but accessible by all the so called 'friends' around me. They could reach in a do whatever they want! Without my consent! And btw, people grabbing your private parts without your explicit consent, is a really serious matter! Just ask those in the me-too movement. Why should a programmers code be exempt from such considerations?
 Basically all of the same arguments that you're giving against 
 having everything in the module being treated as friends of 
 each other can be given against having friends in the first 
 place. It's just that D makes it implicit within the module.
No. In C++, you only declare friends as part of your defined interface. That's kind different to 'everyone around you is your friend. so you need to deal with it'. They are not the same thing, and have to be approached differently.
May 15 2018
next sibling parent bauss <jj_1337 live.dk> writes:
On Tuesday, 15 May 2018 at 10:19:58 UTC, KingJoffrey wrote:
 - Voldemort types (cause yeah...we all use them so often).
Actually yes. Most people who has been writing D for a long time uses them.
May 15 2018
prev sibling next sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 15 May 2018 at 10:19:58 UTC, KingJoffrey wrote:

 Actually, I kinda get it for unit tests.

 Surely there's more??
I use it all the time. One way is to replace what would have been a "Manager" class in Java or elsewhere. module foo.window; class Window { private WindowHandle _handle; private void close() {} } private Window[WindowHandle] _windows; package void closeWindow(Window window) { _windows.remove(window._handle); _window.close(); } This is exactly how I reason about the code and is similar to how I would have structured it in C, but with the benefit of both package- and module-level encapsulation. _windows, window._handle, and window.close are hidden from both the outside world and the package. I can't see any possible reason why I would want to hide the implementation of Window from closeWindow -- they're in the same module! It's not like C++, where multiple classes can belong to multiple namespaces in the same source file. Everything in window.d is in the same namespace.
 And btw, people grabbing your private parts without your 
 explicit consent, is a really serious matter! Just ask those in 
 the me-too movement.

 Why should a programmers code be exempt from such 
 considerations?
D doesn't make that exemption. No one from outside the module has access to your private parts. If you have access to the class, you also have access to the module, and everything is in the same namespace by design, so you're grabbing your own private parts. Why should programmers be prevented from doing that?
May 15 2018
prev sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Tuesday, 15 May 2018 at 10:19:58 UTC, KingJoffrey wrote:
 My own code in D had bugs, cause I didn't realise all my 
 private parts were not just visible, but accessible by all the 
 so called 'friends' around me. They could reach in a do 
 whatever they want! Without my consent!
You've peaked my interest, could you give some details on one or more of these bugs?
May 15 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 15:19:33 UTC, Jesse Phillips wrote:
 On Tuesday, 15 May 2018 at 10:19:58 UTC, KingJoffrey wrote:
 My own code in D had bugs, cause I didn't realise all my 
 private parts were not just visible, but accessible by all the 
 so called 'friends' around me. They could reach in a do 
 whatever they want! Without my consent!
You've peaked my interest, could you give some details on one or more of these bugs?
It's simple. Write a non-member function, contained in the same module as a class, and accidently use a private class member instead of the public getter/setter defined by the interface of that class. It's human error, that will occur time and time again, but will *never* get picked up in D, except through a debugging session, because D does not consider this an error. How can it, if private is not really private? Now the burden is back on the programmer again. Be careful what you put into a module.
May 15 2018
parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Wednesday, 16 May 2018 at 02:05:29 UTC, KingJoffrey wrote:
 On Tuesday, 15 May 2018 at 15:19:33 UTC, Jesse Phillips wrote:
 On Tuesday, 15 May 2018 at 10:19:58 UTC, KingJoffrey wrote:
 My own code in D had bugs, cause I didn't realise all my 
 private parts were not just visible, but accessible by all 
 the so called 'friends' around me. They could reach in a do 
 whatever they want! Without my consent!
You've peaked my interest, could you give some details on one or more of these bugs?
It's simple. Write a non-member function, contained in the same module as a class, and accidently use a private class member instead of the public getter/setter defined by the interface of that class. It's human error, that will occur time and time again, but will *never* get picked up in D, except through a debugging session, because D does not consider this an error. How can it, if private is not really private? Now the burden is back on the programmer again. Be careful what you put into a module.
That isn't a bug. What is the software use case? How did this case differ because someone did this? Global variables and singletons are also frowned on, but call it bad coding not a bug.
May 16 2018
next sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 13:09:22 UTC, Jesse Phillips wrote:
 Global variables and singletons are also frowned on, but call 
 it bad coding not a bug.
Come on, really? that's just word play, much like the use of the 'private' declaration in a class (in D that is). (also, this was not an enterprise application I was developing (D's not ready by a long shot, for the big time, in my opinion) - it was just some code I was playing with in a sandbox (i.e a module).
May 16 2018
prev sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 13:09:22 UTC, Jesse Phillips wrote:
 That isn't a bug. What is the software use case? How did this 
 case differ because someone did this?
Sorry, I didn't realise my example was so complex. Hang on... I'll just put it all into a use case diagram in my new UML tool... I'll get back to you on this.... soon...
May 16 2018
parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Wednesday, 16 May 2018 at 13:33:45 UTC, KingJoffrey wrote:
 On Wednesday, 16 May 2018 at 13:09:22 UTC, Jesse Phillips wrote:
 That isn't a bug. What is the software use case? How did this 
 case differ because someone did this?
Sorry, I didn't realise my example was so complex. Hang on... I'll just put it all into a use case diagram in my new UML tool... I'll get back to you on this.... soon...
No I don't want that, and don't ever show me one. Your example wasn't complex it just didn't describe a bug. A use case should be simple. "list folder content." "make computer speaker beep." "print hello" Even hobby programs have use cases. What was the program doing and how did it not meet those expectations.
May 16 2018
prev sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Tuesday, 15 May 2018 at 02:32:05 UTC, KingJoffrey wrote:
 On Tuesday, 15 May 2018 at 02:00:17 UTC, 12345swordy wrote:
 On Tuesday, 15 May 2018 at 00:28:42 UTC, KingJoffrey wrote:
 On Monday, 14 May 2018 at 19:40:18 UTC, 12345swordy wrote:
 [...]
If 'getting a module to respect the enscapsulation boundaries the programmer puts in place would change the language so 'fundamentally', then the language 'already' presents big problems for large complex application development.
Evidence for this claim please.
- Object independence - Do not violate encapsulation - Respect the interface All large software projects are done in (or moving toward) languages that respect these idioms. Those that don't, are the ones we typically have problems with. Isn't that evidence enough?
That's not evidence, that's pure opinion. There's not a shred of data in that list.
May 15 2018
parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 19:56:58 UTC, Patrick Schluter wrote:
 On Tuesday, 15 May 2018 at 02:32:05 UTC, KingJoffrey wrote:
 On Tuesday, 15 May 2018 at 02:00:17 UTC, 12345swordy wrote:
 On Tuesday, 15 May 2018 at 00:28:42 UTC, KingJoffrey wrote:
 On Monday, 14 May 2018 at 19:40:18 UTC, 12345swordy wrote:
 [...]
If 'getting a module to respect the enscapsulation boundaries the programmer puts in place would change the language so 'fundamentally', then the language 'already' presents big problems for large complex application development.
Evidence for this claim please.
- Object independence - Do not violate encapsulation - Respect the interface All large software projects are done in (or moving toward) languages that respect these idioms. Those that don't, are the ones we typically have problems with. Isn't that evidence enough?
That's not evidence, that's pure opinion. There's not a shred of data in that list.
Actually, that is the history of the evolution of programming large, complex systems, that have to be to correct, safe, and amenable to change. What other approach would work?
May 15 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, May 14, 2018 07:03:35 Dukc via Digitalmars-d wrote:
 On Monday, 14 May 2018 at 07:02:37 UTC, Dukc wrote:
 ------------
 module test;
 void main() { foo.i = 2; }
 of encapsulation
 void foo() { static int i = 1; }
 ------------
meant ------------ module test; void main() { foo.i = 2; } void foo() { static int i = 1; } ------------
If that's what you want, just make it a module-level variable. I don't think that providing access to symbols inside functions like that wouldn really buy us anything. In addition, we rely on function encapsulation for Voldemort types, and the rules for local variables and types are a bit special anyway. Trying to treat them as if they were at the module-level but namespaced by the function seems like it would be complicating things considerably for no real benefit. - Jonathan M Davis
May 14 2018
next sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Monday, 14 May 2018 at 07:59:06 UTC, Jonathan M Davis wrote:
 .. In addition, we rely on function encapsulation for Voldemort 
 types...
Actually, we rely on encapsulation (boundaries) for a lot more than that. How do we get from the orange room to the blue room, if there is no boundary? https://www.youtube.com/watch?v=IP5akjPwqEA (great quote at the end btw - but watch the whole thing first - it'll make more sense)
May 14 2018
prev sibling parent Dukc <ajieskola gmail.com> writes:
On Monday, 14 May 2018 at 07:59:06 UTC, Jonathan M Davis wrote:
 On Monday, May 14, 2018 07:03:35 Dukc via Digitalmars-d wrote:
 On Monday, 14 May 2018 at 07:02:37 UTC, Dukc wrote:
 ------------
 module test;
 void main() { foo.i = 2; }
 void foo() { static int i = 1; }
 ------------
If that's what you want, just make it a module-level variable.
Well, personally I don't care much because using static mutables sucks anyway, and there is rarely a reason to make static immutables just for one function. Enums are for that. Just pointed out that it would be consistent with how classes encapsulate stuff. And the same point goes for eponymous templates, of course.
May 14 2018
prev sibling parent reply Neia Neutuladh <neia ikeran.org> writes:
On Friday, 11 May 2018 at 14:05:25 UTC, KingJoffrey wrote:
 private is not private at all in D, and because of this, 
 classes are fundamentally broken in D (by design apparently).
I find this amusing because D does things exactly like Java. In Java, two sibling nested classes can call private functions on each other. But nobody says that this makes Java's classes fundamentally broken. Like, this just works in Java: public class Protections { public static class Bar { private void bar() { System.out.println("bar"); } } public static class Baz { private void bar(Bar b) { b.bar(); } } public static void main(String[] args) { new Baz().bar(new Bar()); } } A function calling a private method defined in a different class, which calls a private function defined in yet another class! Utter madness! But the sky hasn't fallen, even though there's probably a thousand times as much Java code written as D.
May 11 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Saturday, 12 May 2018 at 04:29:32 UTC, Neia Neutuladh wrote:
 On Friday, 11 May 2018 at 14:05:25 UTC, KingJoffrey wrote:
 private is not private at all in D, and because of this, 
 classes are fundamentally broken in D (by design apparently).
I find this amusing because D does things exactly like Java. In Java, two sibling nested classes can call private functions on each other. But nobody says that this makes Java's classes fundamentally broken. Like, this just works in Java: public class Protections { public static class Bar { private void bar() { System.out.println("bar"); } } public static class Baz { private void bar(Bar b) { b.bar(); } } public static void main(String[] args) { new Baz().bar(new Bar()); } }
Come on, your code example misses my point completely. Take this program below, for example, and tell me that class encapsulation is not broken in D: =============================== module test; import std.stdio : writeln; void main() { Person p = new Person("King Joffrey"); writeln(p.getName); // I designed my class to return this. writeln(p._name); // But D can bypass your intention completely. p._name = "New King"; // even worse, D can nominate another king. writeln(p._name); } class Person { private string _name; public void setName(string name) { this._name = name; } public string getName() { return ProperName(this._name); } public this(string name) { _name = name; } private static string ProperName(string name) { return name ~ " : The one true king!"; } } ==============================
May 11 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 12/05/2018 6:35 PM, KingJoffrey wrote:
 On Saturday, 12 May 2018 at 04:29:32 UTC, Neia Neutuladh wrote:
 On Friday, 11 May 2018 at 14:05:25 UTC, KingJoffrey wrote:
 private is not private at all in D, and because of this, classes are 
 fundamentally broken in D (by design apparently).
I find this amusing because D does things exactly like Java. In Java, two sibling nested classes can call private functions on each other. But nobody says that this makes Java's classes fundamentally broken. Like, this just works in Java: public class Protections {     public static class Bar {         private void bar() { System.out.println("bar"); }     }     public static class Baz {         private void bar(Bar b) { b.bar(); }     }     public static void main(String[] args) {         new Baz().bar(new Bar());     } }
Come on, your code example misses my point completely. Take this program below, for example, and tell me that class encapsulation is not broken in D: =============================== module test; import std.stdio : writeln; void main() {     Person p = new Person("King Joffrey");     writeln(p.getName); // I designed my class to return this.     writeln(p._name); // But D can bypass your intention completely.     p._name = "New King"; // even worse, D can nominate another king.     writeln(p._name); } class Person {     private string _name;     public void setName(string name)     {         this._name = name;     }     public string getName()     {         return ProperName(this._name);     }     public this(string name)     {         _name = name;     }     private static string ProperName(string name)     {         return name ~ " : The one true king!";     } } ==============================
Now move Person into its own module. Boom errors. This is how module systems should work and everything is working correctly :) You will not convince us otherwise.
May 11 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Saturday, 12 May 2018 at 06:38:16 UTC, rikki cattermole wrote:
 Now move Person into its own module.
 Boom errors.

 This is how module systems should work and everything is 
 working correctly :)

 You will not convince us otherwise.
If D treated functions, like it treats classes, then you could do this in D (see below) - and the argument to get around the problems this causes, would be to put each individual function in it's own module. That is in essence, your proposed solution to the problem with class encapsulation in D. ============ module test; void main() { goto wtf; } void foo() { wtf: return; return; } ==========
May 12 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 12/05/2018 7:07 PM, KingJoffrey wrote:
 On Saturday, 12 May 2018 at 06:38:16 UTC, rikki cattermole wrote:
 Now move Person into its own module.
 Boom errors.

 This is how module systems should work and everything is working 
 correctly :)

 You will not convince us otherwise.
If D treated functions, like it treats classes, then you could do this in D (see below) - and the argument to get around the problems this causes, would be to put each individual function in it's own module. That is in essence, your proposed solution to the problem with class encapsulation in D. ============ module test; void main() { goto wtf; } void foo() { wtf: return;     return; } ==========
I see no problem. onlineapp.d(1): Error: label wtf is undefined
May 12 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Saturday, 12 May 2018 at 07:19:47 UTC, rikki cattermole wrote:
 I see no problem.

 onlineapp.d(1): Error: label wtf is undefined
The 'Error' is my point. It's not possible to do this - which is a good thing. D protects the encapsulation unit of the function from such abuse. But the same is not true for classes.
May 12 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, May 12, 2018 07:29:47 KingJoffrey via Digitalmars-d wrote:
 On Saturday, 12 May 2018 at 07:19:47 UTC, rikki cattermole wrote:
 I see no problem.

 onlineapp.d(1): Error: label wtf is undefined
The 'Error' is my point. It's not possible to do this - which is a good thing. D protects the encapsulation unit of the function from such abuse. But the same is not true for classes.
You could argue the same of friend functions in C++. Yes, D weakens the encapsulation of classes in comparison to C++, but it simplifies the language in comparison to needing friend functions like C++ does, and it works _really_ well with stuff like unit testing. Other languages are forced to do stuff like have member functions and variables be protected just so that you can have a unit testing class access them via inheritance, whereas D avoids the need to change the class' API just to be able to test it, because the module has full access to it. Ultimately, it's a tradeoff, and arguments can be made for and against. But in practice, it works extremely well. You're certainly free to not like this particular design choice, but it's one that most of us have no problem with, and I'd be shocked to ever see it change. So, you can be unhappy about it, but complaining isn't going to change anything. You're either going to have to just learn to live with it or not use D. - Jonathan M Davis
May 12 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Saturday, 12 May 2018 at 07:39:04 UTC, Jonathan M Davis wrote:
 Ultimately, it's a tradeoff, and arguments can be made for and 
 against. But in practice, it works extremely well. You're 
 certainly free to not like this particular design choice, but 
 it's one that most of us have no problem with, and I'd be 
 shocked to ever see it change. So, you can be unhappy about it, 
 but complaining isn't going to change anything. You're either 
 going to have to just learn to live with it or not use D.

 - Jonathan M Davis
I'm not so much complaining about it, as warning others of it. D modules do NOT (cannot) respect the encapsulation of the class, and therefore, D modules containing classes, can very easily (to borrow a phrase from Bertrand Meyer) start to resemble "a chunk of Swiss cheese that has been left outside for too long..". As for using D, this is why I don't really use D for anything other than small tasks - where I can happily revert to procedural type programming ( C like), and not have to worry about the issues of broken class encapsulation - which will almost certainly lead to unexpected side-effects, and create whole new 'class' of problems that D programmers have to deal with.
May 12 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, May 12, 2018 08:13:12 KingJoffrey via Digitalmars-d wrote:
 On Saturday, 12 May 2018 at 07:39:04 UTC, Jonathan M Davis wrote:
 Ultimately, it's a tradeoff, and arguments can be made for and
 against. But in practice, it works extremely well. You're
 certainly free to not like this particular design choice, but
 it's one that most of us have no problem with, and I'd be
 shocked to ever see it change. So, you can be unhappy about it,
 but complaining isn't going to change anything. You're either
 going to have to just learn to live with it or not use D.

 - Jonathan M Davis
I'm not so much complaining about it, as warning others of it. D modules do NOT (cannot) respect the encapsulation of the class, and therefore, D modules containing classes, can very easily (to borrow a phrase from Bertrand Meyer) start to resemble "a chunk of Swiss cheese that has been left outside for too long..". As for using D, this is why I don't really use D for anything other than small tasks - where I can happily revert to procedural type programming ( C like), and not have to worry about the issues of broken class encapsulation - which will almost certainly lead to unexpected side-effects, and create whole new 'class' of problems that D programmers have to deal with.
Honestly, the only time that I've ever seen problems related to the fact that private relates to the module and not the struct or class is when there's a problem with a unit tests due to the fact that it's not restricted in the same way that user code would be e.g. - if a symbol is accidentally private, the unit test won't catch that. I have never seen encapsulation issues where someone accidentally uses some private piece of a class or struct by accident elsewhere in the module, and the code therefore ends up with a bug. I'm not about to claim that it's impossible to make such a mistake, but I've never seen one, and in my experience, the fact that everything in a module can access everything else in a module (except that functions can't reach into each other) is a complete non-issue and if anything makes life simpler, because it completely negates the need to worry about friends in those cases where you really do need to reach into the innards of a class or struct within the module. To many of use, you're making a mountain out a mole hill here. While I can understand why what D has done with private might be disturbing to someone when they first come to D, in practice, it's proven to work quite well without causing unexpected side-effects and stray bugs. Maybe it would be worse if D didn't encourage unit testing the way that it does (I don't know), but I can unequivocably say that what D has done with private has worked wonderfully for me and most of the programmers who use D. - Jonathan M Davis
May 12 2018
parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Saturday, 12 May 2018 at 18:19:48 UTC, Jonathan M Davis wrote:
 I have never seen encapsulation issues where someone 
 accidentally uses some private piece of a class or struct by 
 accident elsewhere in the module, and the code therefore ends 
 up with a bug.
Then you've never seem me program. That bug you mention, is something that has often popped up in my program, because the compiler didn't warn me - hey, that stuff is private, shouldn't you be using the getter, or setter. This loss of encapsulation, is why I no longer use classes in D.
May 12 2018
prev sibling parent reply bachmeier <no spam.net> writes:
On Saturday, 12 May 2018 at 06:35:55 UTC, KingJoffrey wrote:

 Come on, your code example misses my point completely.

 Take this program below, for example, and tell me that class 
 encapsulation is not broken in D:

 ===============================
 module test;

 import std.stdio : writeln;

 void main()
 {
     Person p = new Person("King Joffrey");

     writeln(p.getName); // I designed my class to return this.
     writeln(p._name); // But D can bypass your intention 
 completely.

     p._name = "New King"; // even worse, D can nominate another 
 king.
     writeln(p._name);
 }
I think I'm missing something. Why is it a problem that you can do this? How do other languages prevent you from doing it?
May 15 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Tuesday, 15 May 2018 at 14:34:07 UTC, bachmeier wrote:
 I think I'm missing something. Why is it a problem that you can 
 do this? How do other languages prevent you from doing it?
and many from other languages (Go, Rust....) will expect private to mean private...not private..depending on.... They will expect the interface they defined, to be respected. threads like this one, trying to work out why the world is upside down (or seems like it). And don't get me started on public being the default in D .. cause at some point..I gotta get some sleep. -------------- public class Program { public static void Main(string[] args) { Person p = new Person(); //p.name = "King Joffrey"; // dude. this is private! } } public class Person { private string name; public string getName() { return name; } } ---------------
May 15 2018
next sibling parent bachmeier <no spam.net> writes:
On Tuesday, 15 May 2018 at 15:05:45 UTC, KingJoffrey wrote:


 and many from other languages (Go, Rust....) will expect 
 private to mean private...not private..depending on....

 They will expect the interface they defined, to be respected.
I'm not really in agreement with that. If you're coming from another language, you'll have to learn the differences. IMO D's solution is better...maybe you can convince the other languages to change. I haven't read all of the (many) posts in this thread, so I'll leave it at that, since this has probably already been discussed. I didn't understand the example, but it's not actually the case that there's anything "broken", it's just different from what someone would expect if they tried to write C++ or Java in D.
May 15 2018
prev sibling parent reply =?UTF-8?Q?Tobias=20M=C3=BCller?= <troplin bluewin.ch> writes:
KingJoffrey <KingJoffrey KingJoffrey.com> wrote:

 and many from other languages (Go, Rust....) will expect private 
 to mean private...not private..depending on....
Well, that's not entirely true. Visibility in Rust is similar to D. There's no one true language semantics that holds for all languages. That's the point of having different languages.
May 15 2018
next sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 05:59:17 UTC, Tobias Müller wrote:
 KingJoffrey <KingJoffrey KingJoffrey.com> wrote:

 programmers, and many from other languages (Go, Rust....) will 
 expect private to mean private...not private..depending on....
Well, that's not entirely true. Visibility in Rust is similar to D. There's no one true language semantics that holds for all languages. That's the point of having different languages.
actually, private is default in Rust. public is default in D. also, in Rust, private is private within the module, *and* its descendants. I don't believe that is the case in D (someone correct me if I'm wrong)
May 15 2018
next sibling parent reply =?UTF-8?Q?Tobias=20M=C3=BCller?= <troplin bluewin.ch> writes:
KingJoffrey <KingJoffrey KingJoffrey.com> wrote:
 actually, private is default in Rust.
 
 public is default in D.
 
 also, in Rust, private is private within the module, *and* its 
 descendants.
 
 I don't believe that is the case in D (someone correct me if I'm 
 wrong)
The point is, that the module is the abstraction boundary.
May 15 2018
next sibling parent =?UTF-8?Q?Tobias=20M=C3=BCller?= <troplin bluewin.ch> writes:
Tobias Müller <troplin bluewin.ch> wrote:
 KingJoffrey <KingJoffrey KingJoffrey.com> wrote:
 actually, private is default in Rust.
 
 public is default in D.
 
 also, in Rust, private is private within the module, *and* its 
 descendants.
 
 I don't believe that is the case in D (someone correct me if I'm 
 wrong)
The point is, that the module is the abstraction boundary.
s/abstraction/encapsulation/
May 15 2018
prev sibling next sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 06:11:13 UTC, Tobias Müller wrote:
 KingJoffrey <KingJoffrey KingJoffrey.com> wrote:
 actually, private is default in Rust.
 
 public is default in D.
 
 also, in Rust, private is private within the module, *and* its 
 descendants.
 
 I don't believe that is the case in D (someone correct me if 
 I'm wrong)
The point is, that the module is the abstraction boundary.
oh, sorry, I thought your point was that "Visibility in Rust is similar to D."
May 15 2018
prev sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 06:11:13 UTC, Tobias Müller wrote:
 KingJoffrey <KingJoffrey KingJoffrey.com> wrote:
 actually, private is default in Rust.
 
 public is default in D.
 
 also, in Rust, private is private within the module, *and* its 
 descendants.
 
 I don't believe that is the case in D (someone correct me if 
 I'm wrong)
The point is, that the module is the abstraction boundary.
Yeah, but "The unit of object encapsulation in D is the class." - page 175, The D Programming Language, 2010, Andrei Alexandrescu. They cannot both be true. And this leaves room for confusion for new comers to D, unless they all get to page 200 in time, where it says: "In all contexts, private has the same power: it restricts symbol access to the current module (file). This behavior is unlike that in other languages, which limit access to private symbols to the current class only. ... If class-level protection is needed, simply put the class in its own file." Now something like that in the spec I mentioned (on the D website), would not do any harm to the spec, would it?
May 15 2018
prev sibling parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Wednesday, 16 May 2018 at 06:05:31 UTC, KingJoffrey wrote:
 On Wednesday, 16 May 2018 at 05:59:17 UTC, Tobias Müller wrote:
 KingJoffrey <KingJoffrey KingJoffrey.com> wrote:

 programmers, and many from other languages (Go, Rust....) 
 will expect private to mean private...not private..depending 
 on....
Well, that's not entirely true. Visibility in Rust is similar to D. There's no one true language semantics that holds for all languages. That's the point of having different languages.
actually, private is default in Rust. public is default in D. also, in Rust, private is private within the module, *and* its descendants. I don't believe that is the case in D (someone correct me if I'm wrong)
`public` by default is again not a problem. Just apply `private` as necessary. Also, if you want the rust style `private`, D offers `package`, which means private to the modules contained by a package.
May 15 2018
parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 06:17:51 UTC, Uknown wrote:
 `public` by default is again not a problem. Just apply 
 `private` as necessary.
it's not a problem 'if' you 'remember' to use 'private'. private 'within the module' is also not a problem, 'if' you 'remember' that, when using private to encapsulate your class. Again, other mainstream languages have already learn the lesson here, as to why public might not be a great 'default'. knowledge is useful, I get it. so are safe defaults.
 Also, if you want the rust style `private`, D offers `package`, 
 which means private to the modules contained by a package.
Thanks for clarifying this.
May 15 2018
parent reply aliak <something something.com> writes:
On Wednesday, 16 May 2018 at 06:34:35 UTC, KingJoffrey wrote:
 On Wednesday, 16 May 2018 at 06:17:51 UTC, Uknown wrote:
 Also, if you want the rust style `private`, D offers 
 `package`, which means private to the modules contained by a 
 package.
Thanks for clarifying this.
I did not read the rust spec :p, but from the conversations above I believe rust private is not D package. Rust private is private in the module, package in D is all modules in a package. D would be: module mod; private: // put this at top of file and everything below it is not private public void f () {} // explicitly request this one to be public
May 16 2018
parent reply Uknown <sireeshkodali1 gmail.com> writes:
On Wednesday, 16 May 2018 at 07:53:36 UTC, aliak wrote:
 On Wednesday, 16 May 2018 at 06:34:35 UTC, KingJoffrey wrote:
 On Wednesday, 16 May 2018 at 06:17:51 UTC, Uknown wrote:
 Also, if you want the rust style `private`, D offers 
 `package`, which means private to the modules contained by a 
 package.
Thanks for clarifying this.
I did not read the rust spec :p, but from the conversations above I believe rust private is not D package. Rust private is private in the module, package in D is all modules in a package. D would be: module mod; private: // put this at top of file and everything below it is not private public void f () {} // explicitly request this one to be public
Just checked the rust spec [0]. private in rust => accessible from that module and its descendants, which is what package in D is. private in D would be to that module only. [0]: https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html
May 16 2018
parent reply Dave Jones <dave jones.com> writes:
On Wednesday, 16 May 2018 at 08:20:23 UTC, Uknown wrote:
 On Wednesday, 16 May 2018 at 07:53:36 UTC, aliak wrote:

 Just checked the rust spec [0]. private in rust => accessible 
 from that module and its descendants, which is what package in 
 D is. private in D would be to that module only.

 [0]: 
 https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html
Dont know if its been mentioned before but in Delphi / Object Pascal private is accessible to everything in the same module. Same as D.
May 16 2018
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 05/16/2018 04:42 AM, Dave Jones wrote:
 On Wednesday, 16 May 2018 at 08:20:23 UTC, Uknown wrote:
 On Wednesday, 16 May 2018 at 07:53:36 UTC, aliak wrote:

 Just checked the rust spec [0]. private in rust => accessible from 
 that module and its descendants, which is what package in D is. 
 private in D would be to that module only.

 [0]: https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html
Dont know if its been mentioned before but in Delphi / Object Pascal private is accessible to everything in the same module. Same as D.
This is interesting, thanks for the info.
May 16 2018
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/16/2018 6:55 AM, Andrei Alexandrescu wrote:
 On 05/16/2018 04:42 AM, Dave Jones wrote:
 On Wednesday, 16 May 2018 at 08:20:23 UTC, Uknown wrote:
 On Wednesday, 16 May 2018 at 07:53:36 UTC, aliak wrote:

 Just checked the rust spec [0]. private in rust => accessible from that 
 module and its descendants, which is what package in D is. private in D would 
 be to that module only.

 [0]: https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html
Dont know if its been mentioned before but in Delphi / Object Pascal private is accessible to everything in the same module. Same as D.
This is interesting, thanks for the info.
I had no idea. It's either parallel gestation of a great idea, or they took it from D!
May 16 2018
next sibling parent rumbu <rumbu rumbu.ro> writes:
On Wednesday, 16 May 2018 at 16:43:31 UTC, Walter Bright wrote:
 On 5/16/2018 6:55 AM, Andrei Alexandrescu wrote:
 On 05/16/2018 04:42 AM, Dave Jones wrote:
 On Wednesday, 16 May 2018 at 08:20:23 UTC, Uknown wrote:
 On Wednesday, 16 May 2018 at 07:53:36 UTC, aliak wrote:

 Just checked the rust spec [0]. private in rust => 
 accessible from that module and its descendants, which is 
 what package in D is. private in D would be to that module 
 only.

 [0]: 
 https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html
Dont know if its been mentioned before but in Delphi / Object Pascal private is accessible to everything in the same module. Same as D.
This is interesting, thanks for the info.
I had no idea. It's either parallel gestation of a great idea, or they took it from D!
Pascal has the same visibility attributes with the same semantics since Turbo Pascal 5.5 (1989). The only addition was 'published' attribute in 1995, somehow equivalent to 'export' in D. And a vintage nostalgic ad :) http://edn.embarcadero.com/article/images/20803/tp55ad.jpg
May 16 2018
prev sibling next sibling parent Dave Jones <dave jones.com> writes:
On Wednesday, 16 May 2018 at 16:43:31 UTC, Walter Bright wrote:
 On 5/16/2018 6:55 AM, Andrei Alexandrescu wrote:
 On 05/16/2018 04:42 AM, Dave Jones wrote:
 On Wednesday, 16 May 2018 at 08:20:23 UTC, Uknown wrote:
 On Wednesday, 16 May 2018 at 07:53:36 UTC, aliak wrote:

 Just checked the rust spec [0]. private in rust => 
 accessible from that module and its descendants, which is 
 what package in D is. private in D would be to that module 
 only.

 [0]: 
 https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html
Dont know if its been mentioned before but in Delphi / Object Pascal private is accessible to everything in the same module. Same as D.
This is interesting, thanks for the info.
I had no idea. It's either parallel gestation of a great idea, or they took it from D!
Not sure of the exact timing but we're talking at least 17 years ago i think.
May 16 2018
prev sibling parent reply KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 16:43:31 UTC, Walter Bright wrote:
 I had no idea. It's either parallel gestation of a great idea, 
 or they took it from D!
the splitting of the atom was a great idea too..now the world is on the brink of destruction (according to some). how about adding a 'private' attribute on the class, which would mean, private inside the class is only accessible inside the class. I presume the private attribute on the class, is not currently valid in D? This seems unlikely to break anything, while giving the programmer back the control to strategically define interfaces that *must* be used. My neighbour likes to back his car into his driveway. To do so, he drives over my lawn in turns into his driveway. Why? Because he doesn't respect the interface! (his driveway, is his interface, but cause I have no barrier around my lawn, he can do what he likes). Yeah, i know, one class per module might solve this, sure...(put a fence around your lawn approach - but I like it without a fence.). I really do prefer the 'program to interfaces' approach, and, occasionally I would like to have more than one class in the same module (where I deem that appropriate), and still have their interfaces respected. I cannot do this in D. Is there no way this can be accomodated in D (without breaking how things currently work)?
May 16 2018
parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Thursday, 17 May 2018 at 01:36:47 UTC, KingJoffrey wrote:
 how about adding a 'private' attribute on the class, which 
 would mean, private inside the class is only accessible inside 
 the class.

 I presume the private attribute on the class, is not currently 
 valid in D?
or even 'sealed' (as in the actual meaning of the word)
May 16 2018
prev sibling parent KingJoffrey <KingJoffrey KingJoffrey.com> writes:
On Wednesday, 16 May 2018 at 05:59:17 UTC, Tobias Müller wrote:
 KingJoffrey <KingJoffrey KingJoffrey.com> wrote:

 programmers, and many from other languages (Go, Rust....) will 
 expect private to mean private...not private..depending on....
Well, that's not entirely true. Visibility in Rust is similar to D. There's no one true language semantics that holds for all languages. That's the point of having different languages.
Also, my point was not that different languages should not be different. My point was to be aware of the potential for misunderstandings of what 'most' people would expect to hold true. And that point comes back to the very reason I interjected into this discussion (some time back) - because someone though it might be a great idea to introduce a sealed class - but how many people would end up thinking that the keyword 'sealed' means My point holds up, because 'most' (not all, sure) programmers use languages where terminology means the same thing. And I think D needs to be conscious of this when using well known terminologies/concepts, because what I like most about D, is that I can bring my existing knowledge from other mainstream langauges, and start using D productively, very quickly. I cannot say the same for Rust and Go. I almost DO have to go and read the spec before I start using it.
May 15 2018
prev sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Friday, 11 May 2018 at 10:32:39 UTC, KingJoffrey wrote:
 On Friday, 11 May 2018 at 09:47:39 UTC, Dukc wrote:
 You can use D private with Java-like "only for members 
 functions" meaning by putting it alone in it's module, if you 
 want.
Yes. I do know this. But that is essentially.. a hack.
Funny that you call this a hack, see below.
 A 'private' declaration should be part of the implementation of 
 the class, not the class+module. Some say this is just a 
 philosphical difference - I say it's a key design issue for 
 structured programming.
(OT: "structured programming" is generally understood as a concept introduced by the Pascal programming language, and has nothing to do with OOP. You probably use the term in a broader sense here though, and that's OK.) [...]
 So now, in D, to understand the class, you must also understand 
 the module.
Yes.
 This is a backwards step in language design, in my opinion - 
 for various reasons which are easy to examine further.
Sometimes it is good to do a step back, if thereby you correct steps taken in the wrong direction. I have been watching video's of Robert Martin lately, a.k.a. Uncle Bob. His experience is far greater than mine, and his view on encapsulation is pretty clear. Here are a few of his quotes, made in for example [1]: "We had absolutely perfect encapsulation in C." "This all got screwed up by C++." "In C++, header files got polluted with variables and we lost encapsulation. To fix that, we did this really horrible hack: we invented the word 'private'." "'private:' is a terrible hack which attempts to recapture at least some tiny bit of the lost encapsulation that we had in C." "Then [...] we invented the word 'protected' and ever since then we have been figuring out other ways to open that up so now we've got 'package scope' and this cope and that scope and God help us all there's no encapsulation left." "OO has ruined encapsulation." I am not suggesting that everybody should accept that view, but defining modules as the unit of encapsulation cleans up a lot of the mess -- at the cost of having to design a sensible module hierarchy. Encapsulation predates OO and it is not something that can only be had with OO. D puts encapsulation back where it used to be and where it works well: decoupled from OO so that the public interface can be designed independently from inheritance and polymorphism. [1] https://www.youtube.com/watch?v=t86v3N4OshQ&t=20m4s
May 15 2018
prev sibling parent reply Tony <tonytdominguez aol.com> writes:
On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 Also, classes are pretty inconvenient because they are hard to 
 use without the GC.
I find it surprising that a language that had Garbage Collection as one of its' key features, now has that feature looked at as an inconvenience. Was it a design error, or did the wrong class of users latch onto the language?
May 11 2018
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 11/05/2018 8:00 PM, Tony wrote:
 On Friday, 11 May 2018 at 03:32:25 UTC, Uknown wrote:
 Also, classes are pretty inconvenient because they are hard to use 
 without the GC.
I find it surprising that a language that had Garbage Collection as one of its' key features, now has that feature looked at as an inconvenience. Was it a design error, or did the wrong class of users latch onto the language?
GC is the right memory management strategy for a lot of use cases. But there is many more where it isn't the right one. D however is naturally more useful and hence successful in the second set of cases (see Weka.IO and Sociomantic as examples). And no, you can use classes without the GC pretty easily. Its just that structs are even easier still and we do love counting cpu cycles.
May 11 2018
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/10/2018 6:22 AM, Piotr Mitana wrote:
 For those who never coded Scala and don't know sealed classes: a sealed class
is 
 a class which can be only extended in the same source file.
 
      sealed class MyClass {}
 
 Translating to D, a sealed class would could only be extended in the same 
 module.
private class MyClass { } should do the trick.
May 11 2018
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, May 11, 2018 at 04:14:43PM -0700, Walter Bright via Digitalmars-d wrote:
 On 5/10/2018 6:22 AM, Piotr Mitana wrote:
 For those who never coded Scala and don't know sealed classes: a
 sealed class is a class which can be only extended in the same
 source file.
 
      sealed class MyClass {}
 
 Translating to D, a sealed class would could only be extended in the
 same module.
private class MyClass { } should do the trick.
It doesn't; if you do this, you can't pass MyClass outside the module and have other modules invoke its methods. They will get an essentially opaque object. You'll have to resort to ugly wrapper types (defined in the same module) in order to make this work. T -- If creativity is stifled by rigid discipline, then it is not true creativity.
May 11 2018
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/11/2018 4:27 PM, H. S. Teoh wrote:
 On Fri, May 11, 2018 at 04:14:43PM -0700, Walter Bright via Digitalmars-d
wrote:
 On 5/10/2018 6:22 AM, Piotr Mitana wrote:
 For those who never coded Scala and don't know sealed classes: a
 sealed class is a class which can be only extended in the same
 source file.

       sealed class MyClass {}

 Translating to D, a sealed class would could only be extended in the
 same module.
private class MyClass { } should do the trick.
It doesn't; if you do this, you can't pass MyClass outside the module and have other modules invoke its methods. They will get an essentially opaque object. You'll have to resort to ugly wrapper types (defined in the same module) in order to make this work.
The solution is: private class MyClass { ... } public final MyClassSealed : MyClass { } Meaning other modules can use MyClassSealed but cannot derive from it. Other classes inside the module can derive from MyClass as required.
May 12 2018
parent reply Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
On Saturday, 12 May 2018 at 10:27:11 UTC, Walter Bright wrote:
 The solution is:

     private class MyClass { ... }
     public final MyClassSealed : MyClass { }

 Meaning other modules can use MyClassSealed but cannot derive 
 from it. Other classes inside the module can derive from 
 MyClass as required.
It is not. Other modules can use MyClassSealed - yes. Inheritance is possible only im module - yes. But these are two different classes still. If we have two of extending classes: private class Parent {} public final class Child1 : Parent {} public final class Child2 : Parent {} Then it is true that I can inherit Parent outside the module, but I can't use it as well. In this case I can't create an array (other then Object[]) that can hold both Child1 and Child2 outside the module. What I want is to see the supertype *everywhere* and be able to use it for example to create an array of Parents, but not be able to create Child3 : Parent elsewhere then in the module where Parent resides. public final class ParentSealed : Parent {} won't help - it will be just the same as two ChildX classes and still won't have a *visible* supertype other then Object with them. What I am trying to do is: /* foo.d */ module foo; sealed class Parent {} final class Child1 : Parent {} final class Child2 : Parent {} /* bar.d */ module bar; import foo; static this { Parent[] twoParents = [new Child1(), new Child2()]; // Parent is still visible } class Child3 : Parent {} // ERROR: Parent is sealed and cannot be extended outside module foo I don't think that it is possible to rewrite this code without sealed, but still having Child3 illegal and the Parent[] array creatable in the module bar. Another example - taken directly from Scala. In Scala optionals are defined via a set of classes ("[T]" is Scala's version for Java's "<T>"): sealed abstract class Option[T] {} final case class Some[T] extends Option[T] {} object None extends Option[Nothing] {} For the sake of simplicity let's don't dive in how "case class" and "object" are different from typical classes. Also let's assume that Nothing extends T (in fact Scala's Nothing extends every possible type) You can declare an Option[Int] variable everywhere and assign Some(value) or None to it. All three classes are visible from everywhere, but as Option is sealed, you can't create class OnlyOnMonday[T] extends Option[T] {} in the other module (effectively nowhere, as Option is a part of the standard library).
May 12 2018
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/12/2018 8:18 AM, Piotr Mitana wrote:
 What I am trying to do is:
========== a.d ============ class P { private this(); } final class C1 : P { } final class C2 : P { } ======== test.d ============ import a; void foo() { P[] twoPs = [ new C1(), new C2() ]; // works } class C3 : P // fails { } ============================ dmd test a Error: constructor a.P.this is not accessible from module test
May 12 2018
parent reply Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
On Saturday, 12 May 2018 at 15:36:56 UTC, Walter Bright wrote:
 On 5/12/2018 8:18 AM, Piotr Mitana wrote:
 What I am trying to do is:
========== a.d ============ class P { private this(); } final class C1 : P { } final class C2 : P { } ======== test.d ============ import a; void foo() { P[] twoPs = [ new C1(), new C2() ]; // works } class C3 : P // fails { } ============================ dmd test a Error: constructor a.P.this is not accessible from module test
OK, Walter, point for you for this :) I still think that this is a kind of a hack (if I need to create an instance of P directly, I need a factory method - it's also not that clean and obvious), but in fact it effectively seems to do what I want to achieve. Although I consider sealed as a nice addition still to make things nice and clean, I understand that it may be not enough justified to add a new keyword to the language. Thank you for all the opinions on that. :)
May 14 2018
parent Walter Bright <newshound2 digitalmars.com> writes:
On 5/14/2018 1:32 AM, Piotr Mitana wrote:
 OK, Walter, point for you for this :)
Welcs!
May 14 2018
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, May 11, 2018 16:14:43 Walter Bright via Digitalmars-d wrote:
 On 5/10/2018 6:22 AM, Piotr Mitana wrote:
 For those who never coded Scala and don't know sealed classes: a sealed
 class is a class which can be only extended in the same source file.

      sealed class MyClass {}

 Translating to D, a sealed class would could only be extended in the
 same
 module.
private class MyClass { } should do the trick.
Except that if I understand correctly, what the OP wants is to have the class be publicly available while restricting who's allowed to derive from it, with the idea that a particular class hierarchy would have a well-defined set of classes that the person who wrote them had full control over rather than allowing anyone and everyone to derive from any class in the hierarchy except for any final classes at the leaves of the hierarchy. So, you have multiple classes deriving from each other and have them all be public but not don't allow other code to derive from any them. It would arguably be useful for any situation where you want to make a class hierarchy available without letting it be extendable. Whether that's worth adding a feature to the language in order to get, I don't know, but I don't see how it would be possible to achieve with the language as-is. - Jonathan M Davis
May 11 2018
next sibling parent Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
On Friday, 11 May 2018 at 23:28:48 UTC, Jonathan M Davis wrote:
 Except that if I understand correctly, what the OP wants is to 
 have the class be publicly available while restricting who's 
 allowed to derive from it, with the idea that a particular 
 class hierarchy would have a well-defined set of classes that 
 the person who wrote them had full control over rather than 
 allowing anyone and everyone to derive from any class in the 
 hierarchy except for any final classes at the leaves of the 
 hierarchy.
Exactly that is the point. I'll give you an example from an app I've started working on: I developed a little CQRS library. The structure of classes is based on the Entity type - an entity is a piece of data that is sent between a client and a server. Client/server that has received the entity, detects the right Handler class for the given entity class and triggers it. Handler for some entity types will generate other entities, which will be sent to their handlers respectively or sent back over the network to be handled remotely. There are four types of entitites: Commands, Queries, Responses and Events. The most typical patterns are: - Client sends a command to the server. Server uses a CommandHandler to generate resulting Events and EventHandlers to take actions corresponding to them. Eventually it may acknowledge the client that the command has been successfully processed, but without any data in response. - Client sends a Query. The server processes it in QueryHandler, which generates a Response that is sent back. Client uses its ResponseHandler to take actions corresponding to the response, such as presenting the results in the UI. Class-wise, we have: - abstract class Entity, - abstract classes Command, Event, Query and Response, each of them extends Entity, - a number of concrete classes being the particular Commands, Events, Queries and Responses. Now what I want to achieve is prevent library user to extend the Entity class. There are four classes inheriting the Entity class and the entire concept is built around these four. Library's internal code is also constructed to support only these four entity types, which make the concept complete and non-extendable by design. Currently user is able to create a fifth type of Entity, but the library will not - and is not meant to - support it in any other way then throwing an exception. If I made the Entity class private as Walter suggested, I could not create a method to transfer any entity type via network or couldn't create for example a log method that accepts Entity as a parameter (Yes, there is a Variant and Algebraic, but I don't think that it is the right use for them). What I want to have is an entity class visible everywhere, but extendable only inside my library. At the same time I want users to be able to freely extend the Command, Event, Query and Response classes, as this is exactly what the concept is about.
May 11 2018
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 5/11/2018 4:28 PM, Jonathan M Davis wrote:
 [...]
See my reply to H. S. Teoh.
May 12 2018
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, May 11, 2018 at 05:28:48PM -0600, Jonathan M Davis via Digitalmars-d
wrote:
 [...] what the OP wants is to have the class be publicly available
 while restricting who's allowed to derive from it, with the idea that
 a particular class hierarchy would have a well-defined set of classes
 that the person who wrote them had full control over rather than
 allowing anyone and everyone to derive from any class in the hierarchy
 except for any final classes at the leaves of the hierarchy.
[...] I would like to hear of a real-world use case for such a restriction. I honestly can't think of one that doesn't have a design smell of some sort. Isn't the whole point of OOP that user code can extend your classes to implement functionality you have not thought of, rather than you needing to implement everything for them? T -- The best compiler is between your ears. -- Michael Abrash
May 11 2018
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
H. S. Teoh wrote:

 On Fri, May 11, 2018 at 05:28:48PM -0600, Jonathan M Davis via 
 Digitalmars-d wrote:
 [...] what the OP wants is to have the class be publicly available
 while restricting who's allowed to derive from it, with the idea that
 a particular class hierarchy would have a well-defined set of classes
 that the person who wrote them had full control over rather than
 allowing anyone and everyone to derive from any class in the hierarchy
 except for any final classes at the leaves of the hierarchy.
[...] I would like to hear of a real-world use case for such a restriction. I honestly can't think of one that doesn't have a design smell of some sort. Isn't the whole point of OOP that user code can extend your classes to implement functionality you have not thought of, rather than you needing to implement everything for them? T
besides, in D, there is a little sense in restricting class anyway, as we can kinda "extend" it with UFCS at any time.
May 11 2018
prev sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
H. S. Teoh wrote:

p.s. and struct with `alias this` will allow us to extend it with fields 
too. not without using some other tricks, of course, but as there is a 
documented and ligitimate way to workaround any "sealing", i myself see a 
little sense in such feature. the only thing it will be good at is annoying 
users, who will be forced to write workarounds.
May 11 2018