`restricted` member variables

The Zealot zod at zod.zod
Thu Jun 23 10:35:31 UTC 2022


On Thursday, 23 June 2022 at 03:10:46 UTC, Mike Parker wrote:
> On Thursday, 23 June 2022 at 01:45:22 UTC, Paul Backus wrote:
>
>> Your proposal would lead to the following situation:
>>
>>     struct EvenNumber
>>     {
>>         private int n;
>>         invariant (n & 1 == 0);
>>
>>         this(int n) { this.n = n; }
>>
>>         void addTwoMethod() { this.n++; this.n++; } // ok
>>     }
>>
>>     void addTwoUFCS(ref EvenNumber this_)
>>     {
>>         this_.n++; this_.n++; // error - violates invariant
>>     }
>
> I could live with that particular inconsistency. The bigger 
> downside I see is that you'd potentially have multiple 
> invariant checks for the same class on a single function call. 
> And whether that's acceptable depends on how common this is in 
> practice.
>
>>
>> IMO the correct way to view this is that code in the same 
>> module as a class is part of the class's implementation, just 
>> as much as code in the actual class body. (Or if you prefer, 
>> they are both part of the module's implementation, since the 
>> module is the fundamental unit of decomposition here, not the 
>> class.)
>>
>
> As long as the invariant checks only run on those functions 
> that actually touch a private member. There would potentially 
> be checks for multiple classes running before and after each 
> function call, so doing it on every function call in the module 
> is overkill.
>
> And that would also have to include any public member functions 
> of any classes that access any private members of other classes 
> in the same module. It seems more complex to implement than 
> just doing a rewrite to getters/setters.
>
> An even simpler option would be to disallow access to any 
> private members in a module on classes that have invariants. 
> Not something I'd advocate, but a possibility.


Another idea would be to force the programmer to specify _when_ 
the invariant checks happen. :
```
      struct EvenNumber
      {
          private int n;
          invariant (n & 1 == 0);

          this(int n) { this.n = n; }

          void addTwoMethod() { this.n++; this.n++; } // ok
      }

      void addTwoUFCS(ref EvenNumber this_)
      {
          invariant(enter) { // invariant is checked here
             this_.n++; this_.n++;
          }

          invariant(exit) {
             this_.n++; this_.n++;
          } // invariant is checked here

          invariant(access) {
             this_.n++; // invariant is checked here
             this_.n++; // invariant is checked here
          }
      }
```


More information about the Digitalmars-d mailing list