March 13, 2018
On Tuesday, 13 March 2018 at 13:08:44 UTC, psychoticRabbit wrote:
> It also means the author of the class is no longer free to make changes, because all the surrounding code in the module needs to be assessed for impact - this greatly increases the burden of program correctness and maintenance.

The author of the class could just put it in a separate file. As is required by Java and a frequent convention in C++ in C# anyway.

If you can't put it in a separate file, it isn't as encapsulated as you think anyway!
March 13, 2018
On Tuesday, March 13, 2018 02:06:57 psychoticRabbit via Digitalmars-d-learn wrote:
> On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote:
> > private is private to the module, not the class. There is no way in D to restrict the rest of the module from accessing the members of a class. This simplification makes it so that stuff like C++'s friend are unnecessary. If your class in a separate module from main, then main won't be able to access its private members.
> >
> > - Jonathan M Davis
>
> Mmm.. I don't think I like it.
>
> I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation.
>
> No. I don't like it at all.

Well, this thread sure blew up fast...

The decision to make private restrict access to the module certainly has pros and cons, but it works well over all. C++'s solution using friend is more flexible, but it's also more complicated. D's solution removes that extra complication. It also makes the use of private throughout the module more consistent, since unlike C++, D has modules and has to worry about the access level of symbols within a module and not just within classes. Also, given D's built-in unit testing features, being able to have unittest blocks within the module access anything within the module makes testing much easier. No one has to muck with access levels to make stuff available to unit tests as is often the case with languages like Java. And while it might initially seem annoying that you can't restrict access of a member to a class or struct even within a module, it's something that most of us have found to not be a problem in practice. But as with all design decisions, there are tradeoffs, and different people have different opinions about which tradeoffs make the most sense.

The only case I'm aware of where I'd consider the current design to be a problem is that if all of your testing is done within the module, it's harder to catch cases where you screwed up the access level and made something private when you didn't mean to. Being able to access all of the private stuff for tests can be extremely useful, so it's certainly not the case that simply making it so that unittest blocks had only public or package access would be a clear improvement, but it's also not the case that the current design doesn't come with any downsides.

If you really want to restrict access to the class itself, then you can always just declare a class in its own module just like Java forces you to do. That might be annoying if want to put several classes in the same module while restricting their access, but it is a way to enforce full encapsulation if that's what you really want.

Ultimately though, for better or worse, D considers the module to be the primary unit of encapsulation in the language, and most of us find that it works quite well. Given time you may find that you don't mind it as much - or not, but that's the way that D does it, and I very much doubt that that's ever going to change.

- Jonathan M Davis

March 13, 2018
On 3/12/18 10:06 PM, psychoticRabbit wrote:
> On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote:
>>
>> private is private to the module, not the class. There is no way in D to restrict the rest of the module from accessing the members of a class. This simplification makes it so that stuff like C++'s friend are unnecessary. If your class in a separate module from main, then main won't be able to access its private members.
>>
>> - Jonathan M Davis
> 
> Mmm.. I don't think I like it.
> 
> I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation.
> 
> No. I don't like it at all.
> 

OK, so I agree there are drawbacks. But these can be worked around.

In fact, the language author touted this article as sage advice, when in D it's pretty inconvenient: https://forum.dlang.org/post/osr2l3$1ihb$2@digitalmars.com

But when you get right down to it, where you draw the line is arbitrary. Given the power to encapsulate on module boundary, you have lots of different options as to where your functions can reach. You can pretty much put anything into a module, so you aren't limited to class members which can access specific data. With the advent of package modules, you can control quite finely what functions have access to what items, and still have nice simple imports.

If you limit to class members, then you have to do something like C++ friends, which are unnecessarily verbose.

IMO, the module-level encapsulation is the right choice. It helps with a lot of key features:

1. IFTI factory methods
2. unittests
3. co-related structs/classes

-Steve
March 13, 2018
On Tuesday, 13 March 2018 at 02:06:57 UTC, psychoticRabbit wrote:
> On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote:
>>
>> private is private to the module, not the class. There is no way in D to restrict the rest of the module from accessing the members of a class. This simplification makes it so that stuff like C++'s friend are unnecessary. If your class in a separate module from main, then main won't be able to access its private members.
>>
>> - Jonathan M Davis
>
> Mmm.. I don't think I like it.
>
> I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation.
>
> No. I don't like it at all.

Relevant article: http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197


March 13, 2018
On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer wrote:
> On 3/12/18 10:06 PM, psychoticRabbit wrote:
>> [...]
>
> OK, so I agree there are drawbacks. But these can be worked around.
>
> [...]

Private members still have external linkage. Is there anyway to solve this?
March 13, 2018
On Tuesday, 13 March 2018 at 09:14:26 UTC, psychoticRabbit wrote:
> what I don't like, is that I have no way at all to protect members of my class, from things in the module, without moving that class out of that module.
>
> D wants me to completely trust the module, no matter what.
>
> That's make a little uncomfortable, given how long and complex modules can easily become(and aleady are)

I used to feel similarly and understand where you're coming from but after using D for a while the old way feels ridiculous and cumbersome to me. The problem of accidents even in large files can be avoided by using names like "m_length" or "_length": no jury in the world will believe you if you write those then say you didn't know they were private.
March 13, 2018
On Tuesday, 13 March 2018 at 21:36:13 UTC, Arun Chandrasekaran wrote:
> On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer wrote:
>> On 3/12/18 10:06 PM, psychoticRabbit wrote:
>>> [...]
>>
>> OK, so I agree there are drawbacks. But these can be worked around.
>>
>> [...]
>
> Private members still have external linkage. Is there anyway to solve this?

Yeah that's a real WTF.
March 13, 2018
On Tuesday, March 13, 2018 21:36:13 Arun Chandrasekaran via Digitalmars-d- learn wrote:
> On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer
>
> wrote:
> > On 3/12/18 10:06 PM, psychoticRabbit wrote:
> >> [...]
> >
> > OK, so I agree there are drawbacks. But these can be worked around.
> >
> > [...]
>
> Private members still have external linkage. Is there anyway to solve this?

No. There are some folks who want to change it so that you have to use extern to have external linkage, but all of that is a work in progress and would have to be approved by Walter.

- Jonathan M Davis

March 13, 2018
On Tuesday, March 13, 2018 22:25:52 Nathan S. via Digitalmars-d-learn wrote:
> On Tuesday, 13 March 2018 at 21:36:13 UTC, Arun Chandrasekaran
>
> wrote:
> > On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer
> >
> > wrote:
> >> On 3/12/18 10:06 PM, psychoticRabbit wrote:
> >>> [...]
> >>
> >> OK, so I agree there are drawbacks. But these can be worked around.
> >>
> >> [...]
> >
> > Private members still have external linkage. Is there anyway to solve this?
>
> Yeah that's a real WTF.

It's how linking is normally done on Linux with C/C++ and has the advantage of not having to mark any functions as being external like you have to do on Windows. Personally, I've always found having to deal with that with C/C++ on Windows to be extremely annoying, whereas on Linux, shared libraries just work. So, from a usability perspective, I can't say that I'm at all pleased at the idea of having to mark anything as having external linkage in D.

The downside is that it increases the number of symbols which the program has to deal with when linking against a shared library, which can have some negative effects.

- Jonathan M Davis

March 15, 2018
On Tuesday, 13 March 2018 at 22:56:31 UTC, Jonathan M Davis wrote:
> The downside is that it increases the number of symbols which the program has to deal with when linking against a shared library, which can have some negative effects.
>
> - Jonathan M Davis

If I understand correctly it's also responsible for TypeInfo being generated for private classes regardless of whether or not it is ever used.