www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Fixing D's Properties

reply Ender KaShae <astrothayne gmail.com> writes:
Chad J Wrote:


 If the proposed solution is not good enough, please give a better one. 
 Suggestions are welcome and encouraged.
 

I suggest something similar to python properties, for those who are not familior with it a property is created with property(getter, setter) so with my idea property (or inout or some other keyword) would be a new type, sort of like a function or delegate, but with behavior like that described by Chad. The syntax would be somthing like: int getX(){ return x;} void setX(int i){x = i;} property int X(&getX, &setX); the problem is that unlike in python we cannot use keywords to set paramaters so some syntax would have to be made for write only properties, maybe if we used inout instead of property: //read only in int x(&getX); //write only out int x(&setX); //read and write inout int x(&getX, &setX) any read would call the reading function (.reader of the property object) any write would call the writing function (.writer of the property object) so obj.x++ would be the same as: obj.x.writer(obj.x.reader() + 1) when read the property will actually return a special wrapper that sends itself to the writer whenever it is assigned to the address of the property cannot be used as a function or delegate, but can be used as the address of the type
Aug 18 2007
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Ender,

 int getX(){ return x;}
 void setX(int i){x = i;}
 property int X(&getX, &setX);
 
 the problem is that unlike in python we cannot use keywords to set
 paramaters so some syntax would have to be made for write only
 properties, maybe if we used inout instead of property:
 

property int X(void, &setX); property int Y(&getY, void); ?? I'm not sure I like this more than what we have, but it does leave open getting at the functions which I like. It might grow on me.
Aug 18 2007
parent reply "Jb" <jb nowhere.com> writes:
"BCS" <ao pathlink.com> wrote in message 
news:ce0a3343d64a8c9afeb721a0ab0 news.digitalmars.com...
 Reply to Ender,

 int getX(){ return x;}
 void setX(int i){x = i;}
 property int X(&getX, &setX);

 the problem is that unlike in python we cannot use keywords to set
 paramaters so some syntax would have to be made for write only
 properties, maybe if we used inout instead of property:

property int X(void, &setX); property int Y(&getY, void); ?? I'm not sure I like this more than what we have, but it does leave open getting at the functions which I like. It might grow on me.

Delphi does this. _foo int; int getFoo() { return _foo; }; vood setFoo(i: integer) {_foo = i; ); any of the following are valid... property int foo : read getFoo write setFoo; property int foo : read _foo write _foo; property int foo : read getFoo write _foo; property int foo : read _foo; ect.. I converted the Delphi syntax to be more D like, and its just offered for reference, not a proposal as such. So the property specifies either or both read / write, of which either or both can be direct acess to the field or a proxy function. The proxy functions can be virtual and so can be overriden in subclasses. So you get read only, write only, read/write, direct field acess, static function, or virtual function. And you can still expose the function if you want. jb
Aug 19 2007
parent reply Chad J <gamerChad _spamIsBad_gmail.com> writes:
Jb wrote:
 "BCS" <ao pathlink.com> wrote in message 
 news:ce0a3343d64a8c9afeb721a0ab0 news.digitalmars.com...
 Reply to Ender,

 int getX(){ return x;}
 void setX(int i){x = i;}
 property int X(&getX, &setX);

 the problem is that unlike in python we cannot use keywords to set
 paramaters so some syntax would have to be made for write only
 properties, maybe if we used inout instead of property:

property int Y(&getY, void); ?? I'm not sure I like this more than what we have, but it does leave open getting at the functions which I like. It might grow on me.

Delphi does this. _foo int; int getFoo() { return _foo; }; vood setFoo(i: integer) {_foo = i; ); any of the following are valid... property int foo : read getFoo write setFoo; property int foo : read _foo write _foo; property int foo : read getFoo write _foo; property int foo : read _foo; ect.. I converted the Delphi syntax to be more D like, and its just offered for reference, not a proposal as such. So the property specifies either or both read / write, of which either or both can be direct acess to the field or a proxy function. The proxy functions can be virtual and so can be overriden in subclasses. So you get read only, write only, read/write, direct field acess, static function, or virtual function. And you can still expose the function if you want. jb

I like where all of this is going. Then the solution becomes one which allows properties to be treated exactly* as members on the using side, yet allows the underlying functions to be used as well. So BCS, would you be willing to settle for such a solution? * I realize we may have to settle for properties being "close enough" to members, due to addressing.
Aug 19 2007
parent reply BCS <ao pathlink.com> writes:
Reply to Chad,

 I like where all of this is going.
 
 Then the solution becomes one which allows properties to be treated
 exactly* as members on the using side, yet allows the underlying
 functions to be used as well.  So BCS, would you be willing to settle
 for such a solution?

Let's say I wouldn't object to it. (I'm still not totally convinced something /needs/ to be done, but I do thing that it's worth looking at)
 
 * I realize we may have to settle for properties being "close enough"
 to members, due to addressing.

You actually could make pointers to properties work just like members by placing the address of the member in invalid memory locations. Then on a seg-v, check if the address is attached to a property and stuff in the right value. I heard that at one point some computer systems used a something like that (but using illegal op codes) to fake having a floating point unit. (BTW, I am NOT suggesting this be used <G>)
Aug 19 2007
parent reply Chad J <gamerChad _spamIsBad_gmail.com> writes:
BCS wrote:

 
 * I realize we may have to settle for properties being "close enough"
 to members, due to addressing.

You actually could make pointers to properties work just like members by placing the address of the member in invalid memory locations. Then on a seg-v, check if the address is attached to a property and stuff in the right value. I heard that at one point some computer systems used a something like that (but using illegal op codes) to fake having a floating point unit. (BTW, I am NOT suggesting this be used <G>)

Pretty clever! Too bad it seems very hardware dependent.
Aug 20 2007
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Chad J wrote:
 BCS wrote:
 
 * I realize we may have to settle for properties being "close enough"
 to members, due to addressing.

You actually could make pointers to properties work just like members by placing the address of the member in invalid memory locations. Then on a seg-v, check if the address is attached to a property and stuff in the right value. I heard that at one point some computer systems used a something like that (but using illegal op codes) to fake having a floating point unit. (BTW, I am NOT suggesting this be used <G>)

Pretty clever! Too bad it seems very hardware dependent.

It would also be hell to implement on x86 and similar architectures. Too many instructions that access memory, all needing to be emulated...
Aug 20 2007
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
Ender KaShae wrote:
 Chad J Wrote:
 
 
 If the proposed solution is not good enough, please give a better one. 
 Suggestions are welcome and encouraged.

I suggest something similar to python properties, for those who are not familior with it a property is created with property(getter, setter) so with my idea property (or inout or some other keyword) would be a new type, sort of like a function or delegate, but with behavior like that described by Chad. The syntax would be somthing like: int getX(){ return x;} void setX(int i){x = i;} property int X(&getX, &setX);

Or: property int X({ return x; }, (int i) { x = i; });
 the problem is that unlike in python we cannot use keywords to set paramaters
so some syntax would have to be made for write only properties, maybe if we
used inout instead of property:
 
 //read only
 in int x(&getX);
 //write only
 out int x(&setX);
 //read and write
 inout int x(&getX, &setX)

Or: property int ReadonlyX({ return x; }, null); property int WriteonlyX(null, (int i) { x = i; });
 any read would call the reading function (.reader of the property object)
 any write would call the writing function (.writer of the property object)

This is good -- getting the address of the getter and setter functions (&obj.X.reader) will be useful. And getting the address of the property will still allow you to get and set the property. Templates might have trouble with it, though.
 so obj.x++
 
 would be the same as:
 obj.x.writer(obj.x.reader() + 1)
 
 when read the property will actually return a special wrapper that sends
itself to the writer whenever it is assigned to 
 the address of the property cannot be used as a function or delegate, but can
be used as the address of the type 

The address of the property should be an address to a property struct, whose getters and setters would work as usual. Hm... --- class Property(T) { T* value; public void opIncrement() { *value++; } public void opDecrement() { *value--; } public T opAdd(U) (U addend) { return *value + addend; } // ... } class MyClass { private: int _x; public: Property!(int) X; this() { // slightly ugly... X = new Property!(int)(&_x); } } --- If you could overload the dot operator as well, then this and some template magic with __traits would give you everything you want. Without the dot operator, you get everything you need anyway for basic types. And classes are already taken care of. Structs are left out, though.
Aug 19 2007