@property - take it behind the woodshed and shoot it?

Artur Skawina art.08.09 at gmail.com
Sun Jan 27 04:01:26 PST 2013


On 01/27/13 03:48, Rob T wrote:
> On Sunday, 27 January 2013 at 01:11:05 UTC, H. S. Teoh wrote:
>> On Sun, Jan 27, 2013 at 01:15:29AM +0100, Rob T wrote:
>>> We can almost implement properties as a regular struct
>> [...]
>>
>> You do it like this:
>>
>>     import std.stdio;
>>
>>     struct IntProp {
>>         int __impl;
>>
>>         @property /* <-- ah, the irony! */ int value() {
>>             return __impl + 123;
>>         }
>>         alias value this;    // watch this magic
>>
>>         void opAssign(int val) {
>>             __impl = val - 123;
>>         }
>>     }
>>
>>     struct S {
>>         IntProp prop;
>>     }
>>
>>     void main() {
>>         S s;
>>         writeln(s.prop);
>>         s.prop = 321;
>>         writeln(s.prop);
>>     }
>>
>>
>> T
> 
> Ah cool! You don't really need @property however if we adopt the optional () unless that's to be enforced.
> 
> The really nice thing about this, is we can return the struct as a ref, and it still works, and also take the address of the struct and it continues to work.
> 
> Even better I can add more member functions to it and expand on what it can do. The "property as a function" approach is far more limiting and has issues, such as ref returns and taking the address.
> 
> Anyone know what's missing or what won't work with this approach?

   auto w = Widget();
   w.width = 3;
   w.height = 14;
   auto a = w.area;

Consider an implementation of Widget where some/all of these fields are properties.

Also, does adding a "virtual" area property (ie one calculated on demand
from the others) influence the layout of the object? Should it?

IOW, there are many problems with such a solution, some of which can be worked
around, others fixed with relatively small language changes (legalizing
zero-sized objects, making a static-outer implementation cleanly doable etc).

But would there really be enough gain to justify making properties that much more
complicated? The present approach is a reasonable compromise, it just needs proper
call handling.

Consider the case, that is some times brought up here, where you use a library
which at some point is changed and some object fields are replaced by properties.
You recompile your code with that newer version. What keeps working? What breaks?
Which breakages can be avoided? Which ones would you really want to examine and
handle manually?
Any field->property change breaks the ABI, but this can only be avoided by
preemptively using accessors. That doesn't affect @property as such, except that
having some kind of syntax sugar would make creating the required forwarders easier.

Handling @property evaluation correctly not only makes sense, it's necessary to make
them work correctly. But further "improvements" bring few extra benefits, while
complicating the language. Parens-less function calls are a much bigger problem;
I can't see much gain from "cleaning up" the property design.

While killing @property /is/ an option, it's not a good one either, especially if
()-enforcement on all calls doesn't happen before such a change.

artur


More information about the Digitalmars-d mailing list