www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [Suggestion] Implicit chaining of property assignments

Suppose you have a property defined like this:

----------
class Qwert {
     int yuiop() { ... }

     void yuiop(int i) { ... }
}
----------

We have a property getter and setter.  A statement like

     asdfg = qwert.yuiop = 42;

is not valid, since the yuiop setter returns void.  No problem:

----------
class Qwert {
     int yuiop() { ... }

     int yuiop(int i) {
         ...
         return i;
     }
}
----------

However, sometimes it isn't as simple as that.  The retrieval type of 
the property might be different from the type by which it is set.  The 
value might need some conversion or clipping that involves a 
time-consuming process.  Then you're stuck with something like:

----------
class Qwert {
     char[] yuiop() { ... }

     char[] yuiop(int i) {
         ...
         return yuiop;
     }
}
----------

which is wasteful when you're not using the value re-retrieved from the 
property.  If the getter calls an external API, the compiler cannot 
optimise it away, as it can't be sure that the API call has no essential 
side effects.  Moreover, the getter might allocate a new object that 
will be cached, which again would be wasteful if never used.

It would therefore be handy if, where a property setter's return type is 
void, the value of an AssignExpression is taken to be the result of 
getting the property value, which is evaluated only if it's actually 
used.  So,

     asdfg = qwert.yuiop = 42;

would be equivalent to

     qwert.yuiop = 42;
     asdfg = qwert.yuiop;

except that if qwert is an expression, it is evaluated only once.

And similarly,

     hjkl(qwert.yuiop = 42);

equivalent to

     qwert.yuiop = 42;
     hjkl(qwert.yuiop);

and the same with other expression forms.

Of course, property setters would be still allowed to return something, 
which would override the implicit chaining.  This would preserve the 
efficiency of existing code, allowing for the cases when returning the 
new value can be done in a way that bypasses the getter function (e.g. 
by passing the argument straight through, or if the setter API happens 
to return the converted/clipped value as an extra).

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
Sep 06 2004