Thread overview
Class views - a new concept
Jun 26, 2022
forkit
Jun 27, 2022
Dom Disc
Jun 27, 2022
bauss
Jun 27, 2022
forkit
Jun 27, 2022
Arafel
June 26, 2022
So I came up with this idea, based on discussion in another, rather controverial, thread ;-)

In any case, I think this idea deserves it's own thread.

NOTE::it's just an idea, and certainly **not** a proposal.

I'd be interested to know, if anyone else out there knows of any langauge, where a concept like this has been implemented (i.e. a way to restrict specific class member functions to specific class variables).

So...here I introduce a new concept, which (for now), we'll call a 'view'.

It can solve multiple problems, at least for me.

First, it eliminates a need for that very controversial idea of 'private(this)'

Second, it allows fine grained control of member access, to member variables.

Anything declared private, in a view, is simply private to that view.

Destroy! (but try to be civil too)


class myClass
{
    @view
    {
        private:
          int x;

    	public:
          void setX(int x) { this.x = x; }
          int getX( return this.x; }
    }


    private:
      void fred() { this.x = -1; }  // error: fred is not part of the view that contains x
      int waldo() { return this.x; } // error: waldo is not part of the view that contains x

    public:
      void foo() { this.x = -1; }  // error: foo is not part of the view that contains x
      int bar() { return this.x; } // error: bar is not part of the view that contains x
}



June 27, 2022
On Sunday, 26 June 2022 at 23:33:42 UTC, forkit wrote:
> So I came up with this idea, based on discussion in another, rather controverial, thread ;-)
>
> In any case, I think this idea deserves it's own thread.
>
> NOTE::it's just an idea, and certainly **not** a proposal.
>
> I'd be interested to know, if anyone else out there knows of any langauge, where a concept like this has been implemented (i.e. a way to restrict specific class member functions to specific class variables).
>
> So...here I introduce a new concept, which (for now), we'll call a 'view'.
>
> It can solve multiple problems, at least for me.
>
> First, it eliminates a need for that very controversial idea of 'private(this)'
>
> Second, it allows fine grained control of member access, to member variables.
>
> Anything declared private, in a view, is simply private to that view.
>
> Destroy! (but try to be civil too)
>
>
> class myClass
> {
>     @view
>     {
>         private:
>           int x;
>
>     	public:
>           void setX(int x) { this.x = x; }
>           int getX( return this.x; }
>     }
>
>
>     private:
>       void fred() { this.x = -1; }  // error: fred is not part of the view that contains x
>       int waldo() { return this.x; } // error: waldo is not part of the view that contains x
>
>     public:
>       void foo() { this.x = -1; }  // error: foo is not part of the view that contains x
>       int bar() { return this.x; } // error: bar is not part of the view that contains x
> }

What I don't like about this, is that free functions (non-members) can not be part of a @view. Also, this is nothing new. Instead of a @view you can simply use a subclass with static members (so that you don't need an instance of the subclass) and reach the same effect.

What part of "@hidden var" paired with "@sees(var) fun(){ }" don't you like? It provides the same features without needing extra scopes and also allow non-menbers to access @hidden vars if explicitly annotated.
Also it allows more fine-grained control:

class C
{
   @hidden int x, y;

   @sees(x) void funA(int v)
   {
      x = v;
      y = 0; // error, no access
   }

   @sees(x, y) void funB(ref int z)
   {
      int t = x;
      x = y; // ok
      y = z; // ok
      z = t;
   }
}

@sees(y) int funC() // a friend, because it's in the same module
{
   y = x; // error, no access to x, not even for reading
   return y; // ok
}


June 27, 2022
On Monday, 27 June 2022 at 12:00:58 UTC, Dom Disc wrote:
> On Sunday, 26 June 2022 at 23:33:42 UTC, forkit wrote:
>> So I came up with this idea, based on discussion in another, rather controverial, thread ;-)
>>
>> In any case, I think this idea deserves it's own thread.
>>
>> NOTE::it's just an idea, and certainly **not** a proposal.
>>
>> I'd be interested to know, if anyone else out there knows of any langauge, where a concept like this has been implemented (i.e. a way to restrict specific class member functions to specific class variables).
>>
>> So...here I introduce a new concept, which (for now), we'll call a 'view'.
>>
>> It can solve multiple problems, at least for me.
>>
>> First, it eliminates a need for that very controversial idea of 'private(this)'
>>
>> Second, it allows fine grained control of member access, to member variables.
>>
>> Anything declared private, in a view, is simply private to that view.
>>
>> Destroy! (but try to be civil too)
>>
>>
>> class myClass
>> {
>>     @view
>>     {
>>         private:
>>           int x;
>>
>>     	public:
>>           void setX(int x) { this.x = x; }
>>           int getX( return this.x; }
>>     }
>>
>>
>>     private:
>>       void fred() { this.x = -1; }  // error: fred is not part of the view that contains x
>>       int waldo() { return this.x; } // error: waldo is not part of the view that contains x
>>
>>     public:
>>       void foo() { this.x = -1; }  // error: foo is not part of the view that contains x
>>       int bar() { return this.x; } // error: bar is not part of the view that contains x
>> }
>
> What I don't like about this, is that free functions (non-members) can not be part of a @view. Also, this is nothing new. Instead of a @view you can simply use a subclass with static members (so that you don't need an instance of the subclass) and reach the same effect.
>
> What part of "@hidden var" paired with "@sees(var) fun(){ }" don't you like? It provides the same features without needing extra scopes and also allow non-menbers to access @hidden vars if explicitly annotated.
> Also it allows more fine-grained control:
>
> class C
> {
>    @hidden int x, y;
>
>    @sees(x) void funA(int v)
>    {
>       x = v;
>       y = 0; // error, no access
>    }
>
>    @sees(x, y) void funB(ref int z)
>    {
>       int t = x;
>       x = y; // ok
>       y = z; // ok
>       z = t;
>    }
> }
>
> @sees(y) int funC() // a friend, because it's in the same module
> {
>    y = x; // error, no access to x, not even for reading
>    return y; // ok
> }

Not so many @@@@@, D has enough attributes with it already. It's nothing but clutter.

On top of that 'access' would be better than 'sees' or something like 'with' as demonstrated below.

```d
class C
{
   hidden int x, y;

   avoid funA(int v) with (x)
   {
      x = v;
      y = 0; // error, no access
   }

   void funB(ref int z) with (x,y)
   {
      int t = x;
      x = y; // ok
      y = z; // ok
      z = t;
   }
}

int funC() with (y) // a friend, because it's in the same module
{
   y = x; // error, no access to x, not even for reading
   return y; // ok
}

```


But to be fair I don't really like this concept at all.

hidden, I'm okay with, anything more is just too much clutter.
June 27, 2022

On Sunday, 26 June 2022 at 23:33:42 UTC, forkit wrote:

>

I'd be interested to know, if anyone else out there knows of any langauge, where a concept like this has been implemented (i.e. a way to restrict specific class member functions to specific class variables).

Well, you can do it in C++, but it isn't something you would use frequently, so no real reason to add syntax for it.

I believe you can generally do it if you have class private and multiple inheritance.

June 27, 2022
On 27/6/22 1:33, forkit wrote:
> So I came up with this idea, based on discussion in another, rather controverial, thread ;-)
> 
> In any case, I think this idea deserves it's own thread.
> 
> NOTE::it's just an idea, and certainly **not** a proposal.
> 
> I'd be interested to know, if anyone else out there knows of any langauge, where a concept like this has been implemented (i.e. a way to restrict specific class member functions to specific class variables).
> 
> So...here I introduce a new concept, which (for now), we'll call a 'view'.
> 
> It can solve multiple problems, at least for me.
> 
> First, it eliminates a need for that very controversial idea of 'private(this)'
> 
> Second, it allows fine grained control of member access, to member variables.
> 
> Anything declared private, in a view, is simply private to that view.
> 

There are probably some corner cases not covered, and I can't say how it will perform... but it should be already possible to get something really close and usable in most sensible cases:

```d
import std.typecons : Typedef;

class C {
   /* static */ struct View { // Can and should be static if it doesn't access any of C's internals
       // What everything not in this View must use
       public auto i() { return _i; }
       public auto i(int i) { _i = i; }

       // Internals not exposed anywhere else
       private int _i;
    };

    // The magic bit
    private Typedef!View _view;

    // Could be automated and probably improved with some Proxy-like meta-magic
    public auto ref i(Args...)(Args args) { return _view.i(args); }

    // Also something like this could perhaps be made to work:
    // alias i = view.i

    this() {
        i = 1; // Works
        _view.i = 2; // Works, but why would you use it?
        // view._i = 3 // Fails
    }
}

// Inheritance works as you'd expect
class D : C { }

void main() {
    C c = new C();
    c.i = 4; // Works
    c._view.i = 5; // Works, but why would you use it?
    // c.view._i = 6; // Fails

    D d = new D();
    d.i = 7 // Works, etc.;
}
```

June 27, 2022
On Monday, 27 June 2022 at 12:08:27 UTC, bauss wrote:
>
> But to be fair I don't really like this concept at all.
>
> hidden, I'm okay with, anything more is just too much clutter.

yes. after working through this idea some more, I found this is not such a good idea afterall ;-)

I still like the idea of enhancing D's invariant function, so i can do somethiing like this (see futher below).

i.e. in one tiny piece of code, I know what accesses these private member variables, and the compiler can statically demonstrate whether my code violates such invariants.

Here I use private(this), so being private to the class, only member functions can access it. But if it was 'private', it would be private to the module, and your invariant declaration could include 'free functions' (in the same module) as well.

Again, this idea too is not thought through to completion, but as yet, I don't see any red flags (in the idea itself).

class C
{
    private(this):
     int x, y, z;

    invariant()
    {
        // restrict certain member functions to certain member variables.
        assert( @restrictedMemberAccess {x, y : setXY, getX, getY};
    }

    setXY(int x, int y) { x = x; y = y } // fine
    int getX( return x); // fine
    int getY( return y); // fine

    void foo( x = 0; ); // noCanDo! foo is not in the above list.
    void bar( z = 0; ); // fine. no invariants declared. so normal rules apply.
}