June 05, 2022
On Sunday, 5 June 2022 at 04:49:44 UTC, forkit wrote:
>

btw.

here is a simple example, for demonstration purposes only, of the change that I'd like to see in D:

It's benefit seems very obvious to me ;-)

First, the invariants of the class are now upheld by the compiler.

Second, those of us who expect invariants to be upheld, can now have it.

Third, it's completely optional. Nobody has to change anything they currently do. If you don't want it, don't use it.


// ----
module test;

// example: @private is an access specifier, that works just as private does,
// except, that @private is encapsulated to the class (or struct).

class ID
{
    import std.string;

    @private:
        string _id;

    public
        void setID(string id)
        {
            assert(isNumeric(id));
            _id = id;
        }
}

unittest
{
    import std.stdio;

    ID id = new ID();

    id.setID("123"); // Fine. The invariant is maintained.
    writeln(id._id);

    id._id = "dsa"; // This would violate the invariant.
                    // The compiler would never allow this with @private
    writeln(id._id);
}

// -----

June 05, 2022

On Saturday, 4 June 2022 at 14:40:10 UTC, zjh wrote:

>

For me, it would be better ,if I could encapsulate at class level.In any case, I don't want the outside to affect my class inside.

C++ "class level privacy" needs to have "friends", else you cannot create top-level functions that have access to the private members.
But these "friends" destroy the whole purpose of "private":
Anybody can declare friends, without even touching the file where the class is defined, and thereby access things that shouldn't even be visible to them (implementation details or even security relevant things)!
In D you need to change the file where a class is defined if you need to access its privates - this is much easier visible and in a larger team can't be hidden from the person responsible for that class.

forkit wrote:

>

my argument is not favouring one or the other. It's favouring the
'option' to have both.

But C++ private is just working by convention - it doesn't enforce anything (because it can be circumvented with friends, same problem as with const which can be circumvented with mutable).
By adding this broken thing to D it will be less save and can't guarantee any privacy anymore, just like with C++ now.

June 05, 2022

On Sunday, 5 June 2022 at 19:41:36 UTC, Dom Disc wrote:

>

Anybody can declare friends, without even touching the file where the class is defined, and thereby access things that shouldn't even be visible to them (implementation details or even security relevant things)!

No, I don't think so:

«If a program contains more than one definition of a type, then each definition must be equivalent.»

https://en.wikipedia.org/wiki/One_Definition_Rule

Whether compiler check for it, or not, is another issue.

June 05, 2022

On Sunday, 5 June 2022 at 19:48:03 UTC, Ola Fosheim Grøstad wrote:

>

On Sunday, 5 June 2022 at 19:41:36 UTC, Dom Disc wrote:

>

Anybody can declare friends, without even touching the file where the class is defined, and thereby access things that shouldn't even be visible to them (implementation details or even security relevant things)!

No, I don't think so:

«If a program contains more than one definition of a type, then each definition must be equivalent.»

?!?
You don't need to re-declare the class. You can simply overwrite a friend function. Ok, if the class don't have any friends, this doesn't work. But most of the time there are some...

June 05, 2022

On Sunday, 5 June 2022 at 20:42:59 UTC, Dom Disc wrote:

>

You don't need to re-declare the class. You can simply overwrite a friend function.

Not exactly sure by what you mean by overwrite, you mean defining the function twice?

Encapsulation does not protect against sabotage, only against mistakes.

June 05, 2022

On Sunday, 5 June 2022 at 21:40:18 UTC, Ola Fosheim Grøstad wrote:

>

Encapsulation does not protect against sabotage, only against mistakes.

Fair enough.

June 05, 2022
On Sunday, 5 June 2022 at 21:40:18 UTC, Ola Fosheim Grøstad wrote:
> On Sunday, 5 June 2022 at 20:42:59 UTC, Dom Disc wrote:
>> You don't need to re-declare the class. You can simply overwrite a friend function.
>
> Not exactly sure by what you mean by overwrite, you mean defining the function twice?
>
> Encapsulation does not protect against sabotage, only against mistakes.

+1 .. although the benefits of encapsulation are much greater than that.

Encapsulation, along with the concepts of decompostion and abstraction, are the three most important concepts in programming. None of which are there to protect against sabotage.

Because of the limitation of the human capacity for dealing with complexity, we must organise our code into chunks, in this case, a class, so that we can capture common properties 'in one place'. Now we can reason about it locally.

Also now, even with our limited human capacity for managing complexity, we can begin to build up a complex system. Horray for the class!

It's hard to have an object in D (and instantiation of a class) that has well defined behaviour, when there is no mechanism to protect that behaviour (from mistakes -> from surrounding code in the same module).

My example with the unit-test demonstrates that. One class per module does not solve that problem either btw.

D's approach *includes* the module as an abstraction by which you can manage complexity. But it seems to me, that it has come at the expense of the class abstaction -> by that I mean, as long as there is no way to enforce the invariants of the abstraction -> from any surrounding code in same module, then mistakes will be made. Even in unit-test code!

And whether or not mistake are in fact made, is irrelevant. The fact that mistakes can be made, requires one to audit ALL the surrounding code in the module!

So just the option to have a really private property would be nice.

It takes nothing away from anyone, and doesn't force anything on anyone. It's purely opt-in, and will no doubt, contribute to better encapsulation, and hence better software. Ideally, you'd choose to default to @private in your programming guidelines, and only when this doesn't work for you, should you remove the @. This would encourage better encapsulation I believe. Some of those D modules in phobos.. grr...!!

On what basis (other than an idealogical objection to 'change'), would someone object to such an 'option'?

Just imagine if D had a leaky module abstraction - but you were told to deal with that, by avoiding making mistakes ;-)

June 06, 2022

On Sunday, 5 June 2022 at 19:41:36 UTC, Dom Disc wrote:

>

[...]
I usually don't use the pointer very much, and haven't used friend.
I'm not that complicated.
I directly expose the 'members' . If the 'private members' related to realization .They are of course private, avoid unintentional use .
Class only needs to expose a few 'functions + members', and everything is OK
Class is the smallest unit of encapsulation.
D but do not add it. You do not know which code has changed your private variables in the same module .
It's so interesting.

>

Anybody can declare friends, without even touching the file

I don't know .I haven't use `friend'.

June 06, 2022
On Monday, 6 June 2022 at 00:07:53 UTC, zjh wrote:
> On Sunday, 5 June 2022 at 19:41:36 UTC, Dom Disc wrote:
>> [...]
> I usually don't use the `pointer` very much, and haven't used `friend`.
> I'm not that complicated.
> I directly expose the `'members'` . If the `'private members'` related to realization .They are of course `private`, avoid unintentional use .
> Class only needs to expose a few `'functions + members'`, and everything is OK
> Class is the smallest unit of encapsulation.
> `D` but do not add it. You do not know which code has changed your `private variables` in the same module .
> It's so interesting.
>
>> Anybody can declare friends, without even touching the file
>
> I don't know .I haven't use `friend'.

Well, if you use D, then you do ;-)

Cause the module is the friend you will always have, no matter what ;-)
June 06, 2022

On Monday, 6 June 2022 at 00:33:30 UTC, forkit wrote:

>

Well, if you use D, then you do ;-)

Cause the module is the friend you will always have, no matter what ;-)

You're right.