May 11, 2018
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
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
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
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
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
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
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
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
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 12, 2018
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.