June 21, 2022

On Tuesday, 21 June 2022 at 08:55:19 UTC, Ola Fosheim Grøstad wrote:

>

On Tuesday, 21 June 2022 at 08:37:55 UTC, Max Samukha wrote:

>

I am actually against any changes to the current situation. Module-level private is designed to break encapsulation, so breaking the invariants by module-level functions is expected.

Yes, I agree. Either be consistent with the idea that the module is the boundary for encapsulation or not.

It is better to give priority to plugging the holes that prevent people from writing code than preventing the compiler from accepting ill-conceived programs.

The current D compiler accepts too many programs, but that can be fixed with a linter.

D will do anything to not have class private.

June 21, 2022
On Tuesday, 21 June 2022 at 10:32:10 UTC, The Zealot wrote:
> On Tuesday, 21 June 2022 at 01:18:38 UTC, forkit wrote:
>> On Monday, 20 June 2022 at 11:04:16 UTC, Mike Parker wrote:
>>> [...]
>>
>> I don't want to rehash it either, so I'll limit this to one post in this thread.
>>
>> [...]
>
> you can already express the intent more clearly by putting the class in either a separate module, or function scope.
> we _do_ understand your point, we disagree on it's usefulness and the complexity it adds to the language.

What complexity are you talking about? It'll hardly make a difference, if anything adds complexity to the language then it's stuff like dip1000, importC and the whole attribute hell D has bestowed upon itself etc. not anything related to "class private".

If you think "class private" is too complex, then arguably programming isn't for you.

If you think it adds complexity to the language and/or compiler, then arguably you don't understand how a programming language is developed.

There's literally nothing complex about something being private to a class. It's a concept that has existed before D was even a language. Arguably module private is more complex.

Not to mention some of those things were just added over night and/or don't work as intended.

I'm not against module private, but it sure would be nice to have the opportunity to opt-out sometimes.

But that's besides the point of this discussion.

I do believe this whole thread wouldn't be necessary if class private really existed.

It will solve this issue and many more, it will hardly create any issues that people will not be able to overcome.

Every piece of code existing today will work the same way, the only difference will be in future apis.
June 21, 2022

On Tuesday, 21 June 2022 at 10:36:32 UTC, The Zealot wrote:

>

if anything, i'd like to see more control over when invariants are actually checked.

something like

invariant(default)
    {
        assert(1 <= day && day <= 31);
        assert(0 <= hour && hour < 24);
    }
invariant(always) {
        assert(1 <= sec && sec <= 60);
}

You can already do this, just add an or-clause to a compile time boolean constant.

assert((!precise_invariant) || (1 <= day && day <= 31));

But the class invariant should only be tested on member-function entry in debug-mode.

In release mode the invariant should be assumed to hold on entry and can be used for optimizations (it should still be tested on exit).

So this:


class always_even {
   private int x;
   invariant { assert(x%2==0); }
   void triple(){
      x *= 3;
      if (x&1) writeln("found one");
   }
   // more code
}

should become this:


class always_even {
   private int x;
   tripple(){
      // assume(x%2==0)
      x *= 3;
      assert(x%2==0);
   }
   …
}

Or even this (with a decent optimizer):


class always_even {
   private int x;
   tripple(){
      // assume(x%2==0)
      x *= 3;
      // assert(x%2==0);
   }
   …
}

With invariants turned off, the result will be worse as there is no indication that the lowest bit of x is constant 0:

class always_even {
   private int x;
   void triple(){
      x *= 3;
      if (x&1) writeln("found one");
   }
   …
}

June 21, 2022

On Tuesday, 21 June 2022 at 11:06:17 UTC, bauss wrote:

>

D will do anything to not have class private.

Yes, but you can do it with @UDA + linter.

That is a much better approach than getting more complexity into the language (anything more complex than a «hidden» specifier should be rejected)

June 21, 2022

On Tuesday, 21 June 2022 at 11:23:36 UTC, Ola Fosheim Grøstad wrote:

>

On Tuesday, 21 June 2022 at 11:06:17 UTC, bauss wrote:

>

D will do anything to not have class private.

Yes, but you can do it with @UDA + linter.

That is a much better approach than getting more complexity into the language (anything more complex than a «hidden» specifier should be rejected)

I don't agree that it's a better approach because then you also have to use a linter and can't just resort to using the compiler.

Unless D shipped with a linter that worked with every editor and/or could be put into your build system easily, then I don't think it's a better solution.

I'd much rather have the compiler yield an error to me and then fix that, than relying on yet another third party tool.

June 21, 2022

On Tuesday, 21 June 2022 at 11:20:46 UTC, Ola Fosheim Grøstad wrote:

>

On Tuesday, 21 June 2022 at 10:36:32 UTC, The Zealot wrote:

>

if anything, i'd like to see more control over when invariants are actually checked.

something like

invariant(default)
    {
        assert(1 <= day && day <= 31);
        assert(0 <= hour && hour < 24);
    }
invariant(always) {
        assert(1 <= sec && sec <= 60);
}

You can already do this, just add an or-clause to a compile time boolean constant.

assert((!precise_invariant) || (1 <= day && day <= 31));

But the class invariant should only be tested on member-function entry in debug-mode.

In release mode the invariant should be assumed to hold on entry and can be used for optimizations (it should still be tested on exit).

So this:


class always_even {
   private int x;
   invariant { assert(x%2==0); }
   void triple(){
      x *= 3;
      if (x&1) writeln("found one");
   }
   // more code
}

should become this:


class always_even {
   private int x;
   tripple(){
      // assume(x%2==0)
      x *= 3;
      assert(x%2==0);
   }
   …
}

Or even this (with a decent optimizer):


class always_even {
   private int x;
   tripple(){
      // assume(x%2==0)
      x *= 3;
      // assert(x%2==0);
   }
   …
}

With invariants turned off, the result will be worse as there is no indication that the lowest bit of x is constant 0:

class always_even {
   private int x;
   void triple(){
      x *= 3;
      if (x&1) writeln("found one");
   }
   …
}

sorry, i wasn't clear what i meant. i meant add the ability to control when invariants checks are inserted by the compiler. for example a way to specify that you want the invariant checked after each access to any member, as well as "the class invariant should only be tested on member-function entry in debug-mode".
but it's mainly a suggestion for performance reasons.

June 21, 2022

On Tuesday, 21 June 2022 at 12:18:35 UTC, bauss wrote:

>

On Tuesday, 21 June 2022 at 11:23:36 UTC, Ola Fosheim Grøstad wrote:

>

(anything more complex than a «hidden» specifier should be rejected)
...

I do agree that it shouldn't be more complex than just a "hidden" keyword tho.

Ex. hidden int x should be the only thing, nothing more and nothing less.

I don't think it's necessary to add anything more complex like controlling who has access etc.

June 21, 2022

On Tuesday, 21 June 2022 at 12:18:35 UTC, bauss wrote:

>

I'd much rather have the compiler yield an error to me and then fix that, than relying on yet another third party tool.

I'd rather see nothing than more annoying syntax.

Since over half of all class attributes should be class-private the syntax has to be short and clean.

June 21, 2022

On Tuesday, 21 June 2022 at 12:20:15 UTC, bauss wrote:

>

On Tuesday, 21 June 2022 at 12:18:35 UTC, bauss wrote:

>

On Tuesday, 21 June 2022 at 11:23:36 UTC, Ola Fosheim Grøstad wrote:

>

(anything more complex than a «hidden» specifier should be rejected)
...

I do agree that it shouldn't be more complex than just a "hidden" keyword tho.

Ah, ok. So we agree :)

June 21, 2022

On Tuesday, 21 June 2022 at 11:06:17 UTC, bauss wrote:

>

D will do anything to not have class private.

To the contrary, it doesn't have that today and is doing nothing.

If you want it to do something, you need to justify that it is worth doing.

So far, all we got is "This is mandatory as per my definition of OOP", which is not a convincing argument.

This is especially not convincing because many people here have been using D for many years, and most of them had a "hu, that's weird" moment when they figured out how private was working. And then figured out that the current behavior is actually much more useful in practice.