digitalmars.D - Class views - a new concept
- forkit (39/39) Jun 26 2022 So I came up with this idea, based on discussion in another,
- Dom Disc (32/71) Jun 27 2022 What I don't like about this, is that free functions
- bauss (30/116) Jun 27 2022 Not so many @@@@@, D has enough attributes with it already. It's
- forkit (32/34) Jun 27 2022 yes. after working through this idea some more, I found this is
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/9) Jun 27 2022 Well, you can do it in C++, but it isn't something you would use
- Arafel (39/62) Jun 27 2022 There are probably some corner cases not covered, and I can't say how it...
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
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
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: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.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
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
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
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