www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Class views - a new concept

reply forkit <forkit gmail.com> writes:
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
}
Jun 26 2022
next sibling parent reply Dom Disc <dominikus scherkl.de> writes:
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 }
Jun 27 2022
parent reply bauss <jj_1337 live.dk> writes:
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.
Jun 27 2022
parent forkit <forkit gmail.com> writes:
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. }
Jun 27 2022
prev sibling next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
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.
Jun 27 2022
prev sibling parent Arafel <er.krali gmail.com> writes:
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.; } ```
Jun 27 2022