March 18, 2018
On Sunday, 18 March 2018 at 05:01:39 UTC, Amorphorious wrote:
>
> The fact is, the creator of the class is also the creator of the module.. and preventing him from having full access to the class is ignorant. He doesn't need to encapsulate himself. Encapsulation is ONLY meant to reduce dependencies. If the programmer, probably someone like you, can't trust himself to understand his own code then he shouldn't be coding.
>

btw.

I am talking here about 'encapsulation' not 'information hiding' (although the two terms are often considered related).

Clearly, there is no point in hiding information contained within the module, from the implementer of the module. That's just silly.

However, are there no scenarios in which the person writing that module, would not want to encapsulate their class, or some parts of it, from the rest of the module (while not being forced to put the class in it's own file)?

If the answer is certainly no, not under any circumstances, then fine, my idea is not worth any further consideration.

And by no, I mean no for all, not just you.


March 18, 2018
On Saturday, 17 March 2018 at 23:54:22 UTC, psychoticRabbit wrote:
> On Saturday, 17 March 2018 at 21:33:01 UTC, Adam D. Ruppe wrote:
>> On Saturday, 17 March 2018 at 21:22:44 UTC, arturg wrote:
>>> maybe extend that to a list of types?
>>
>> this is basically what C++ friend does and D was trying to avoid the complexity of
>
> Really, the complexity of 'friend' comes from people abusing it.
>
> In D, I would prefer no breaking change here. Leave private as it is.
>
> Just a simple attribute that only applies within a class, and only to private members within that class.
>
> @strictly private string firstName_;
>
> Nothing outside of the class, not even the module, can access this now. It's all encapsulated.
>
> It breaks nothing (AFAIK).
> It's very clear what the intention is here.
> It's an easy attribute to remember.
> It restores the principle of class enscapsulation within a module, for when it's really needed.
>
> Now D programmers would have the best of both worlds.

Yesterday i thought to reuse `super`:

struct Foo
{
super private:
    int _stats;
    int _field;
public:
    int field(){_stats++; return _field;}
    void field(int value){_stats++; _field = value;}
}

BTW i think adding this can be useful. The FreePascal language has `strict private` for example.
March 18, 2018
On Sunday, 18 March 2018 at 10:14:30 UTC, Alain Soap wrote:
> BTW i think adding this can be useful. The FreePascal language has `strict private` for example.

" Private - All fields and methods that are in a private block, can only be accessed in the module (i.e. unit) that contains the class definition. They can be accessed from inside the classes’ methods or from outside them (e.g. from other classes’ methods)"

" Strict Private - All fields and methods that are in a strict private block, can only be accessed from methods of the class itself. Other classes or descendent classes (even in the same unit) cannot access strict private members. "

https://www.freepascal.org/docs-html/ref/refse34.html

interesting...someone else clearly had the idea.

hey..perhaps I'm not a moron after all.
March 18, 2018
On Sunday, 18 March 2018 at 09:56:31 UTC, psychoticRabbit wrote:
> However, are there no scenarios in which the person writing that module, would not want to encapsulate their class, or some parts of it, from the rest of the module (while not being forced to put the class in it's own file)?
>
> If the answer is certainly no, not under any circumstances, then fine, my idea is not worth any further consideration.
>
> And by no, I mean no for all, not just you.

I assume, that the following statement is equivalent to yours:

´´´
Are there any scenarios in which the person writing the class, would want to encapsulate their class, or some parts of it, from the rest of a module (while being forced to put the class in this module)?
´´´

The answer is no. As the person which is writing the class has always the power to decide which module to edit to put the class in.

And due this fact, the statement

> The fact is, the creator of the class is also the creator of the module..

is the coolest semantic statement of the whole thread so far, I think :)
March 18, 2018
On Sunday, 18 March 2018 at 10:45:55 UTC, psychoticRabbit wrote:
> On Sunday, 18 March 2018 at 10:14:30 UTC, Alain Soap wrote:
>> [...]
>
> " Private - All fields and methods that are in a private block, can only be accessed in the module (i.e. unit) that contains the class definition. They can be accessed from inside the classes’ methods or from outside them (e.g. from other classes’ methods)"
>
> " Strict Private - All fields and methods that are in a strict private block, can only be accessed from methods of the class itself. Other classes or descendent classes (even in the same unit) cannot access strict private members. "
>
> https://www.freepascal.org/docs-html/ref/refse34.html
>
> interesting...someone else clearly had the idea.
>
> hey..perhaps I'm not a moron after all.

Change your pseudo.
March 18, 2018
On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:

>
> D is not C++, C#, or Java. C++ uses friend to get around the issue. Java has no solution. I don't know about C#.
>

Java has four protection levels. If you don't explicitly specify [private, protected, public] the protection level is implicitly "package-private". That means that any class in the same package can access that attribute. I believe that Java packages are identical to D packages.

March 18, 2018
On Sunday, March 18, 2018 18:04:13 Tony via Digitalmars-d-learn wrote:
> On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote:
> > D is not C++, C#, or Java. C++ uses friend to get around the issue. Java has no solution. I don't know about C#.
>
> Java has four protection levels. If you don't explicitly specify [private, protected, public] the protection level is implicitly "package-private". That means that any class in the same package can access that attribute. I believe that Java packages are identical to D packages.

They're similar, but there are differences. For instance, you can do package(a) in D in order to do something like put the stuff in a.b.c in package a rather than a.b. Also, package functions in D are never virtual, which I expect is not the case for Java. The whole situation is also complicated somewhat by the fact that D allows pretty much anything at module-level, whereas as Java requires one class per module, though I'm not sure that that has much direct effect on package itself other than the fact that it's possible in D to mark stuff package that isn't in a class.

- Jonathan M Davis

March 18, 2018
On 3/17/18 5:56 AM, Nick Treleaven wrote:
> On Tuesday, 13 March 2018 at 13:59:00 UTC, Steven Schveighoffer wrote:
>> If you limit to class members, then you have to do something like C++ friends, which are unnecessarily verbose.
> 
> Not if you also have a module-level visibility modifier, which could have been `module`.

If we could go back in time and talk with a young Walter about the consequences of choosing the scheme the way it is, maybe he might have made different choices, but at this point, it's hard to change it.

Note, again, you can do pretty much every privacy scheme you want with package modules today. Before, it was a lot less nice.

It's pretty simple: all your friends go into the module. All your external functions that should only use the public API have to go elsewhere. I think the thing that bites people is simply that they aren't used to it.

> 
>> IMO, the module-level encapsulation is the right choice. It helps with a lot of key features:
>>
>> 1. IFTI factory methods
> 
> Aren't these mainly because constructors can't use IFTI, unlike C++17, 

While this is a limitation that I wish wasn't there, constructors aren't always the best way to build a type.

But there are other reasons to put functions that access private pieces outside the aggregate. For instance, if you want to accept a struct by value.

> 
>> 2. unittests
> 
> Documented unittests should not be allowed to use private symbols, I just filed this:
> https://issues.dlang.org/show_bug.cgi?id=18623
Why not?

unittest
{
   auto foo = new Foo;
   assert(foo.internalbuffer.empty); // note, this is a private symbol.
}

I can do the same thing in ddoc, but without the benefit of having the unit test run. Forcing me to do it that way is just annoying (I will have to duplicate the code).

-Steve
March 18, 2018
On Sunday, 18 March 2018 at 18:32:42 UTC, Jonathan M Davis wrote:

>
> They're similar, but there are differences. For instance, you can do package(a) in D in order to do something like put the stuff in a.b.c in package a rather than a.b.

Is there a known situation where it makes sense to put module c in directory/package b - rather than directory/package a, and then tell the D compiler to treat it like it was in directory/package a?
March 18, 2018
On Sunday, March 18, 2018 18:59:39 Tony via Digitalmars-d-learn wrote:
> On Sunday, 18 March 2018 at 18:32:42 UTC, Jonathan M Davis wrote:
> > They're similar, but there are differences. For instance, you can do package(a) in D in order to do something like put the stuff in a.b.c in package a rather than a.b.
>
> Is there a known situation where it makes sense to put module c in directory/package b - rather than directory/package a, and then tell the D compiler to treat it like it was in directory/package a?

I don't think that you can have anything in a/b/c.d marked as if it were in package a/z. It's only for putting stuff higher up in the package hierarchy while allowing it to be placed in modules deeper in the hierarchy, not for moving it laterally within the package hierarchy. One place where it's used (and which IIRC was the motivating reason for its implementation) is std.internal.* in Phobos. At least some of what's there is marked with package(std) (and probably all of it should be, but a lot of it predates the improvement to package). That way, stuff that's essentially private to Phobos can be organized there but be used by anything in Phobos, whereas without the improvement to package, they'd all have to be modules directly under std (probably all with internal in their module names) in order to have them being treated as being in the std package. So, ultimately, it's about better organization and probably is something that only makes sense for when entire modules are essentially private to a library and not for modules that mix public and package symbols.

- Jonathan M Davis