Property discussion wrap-up
Steven Schveighoffer
schveiguy at yahoo.com
Mon Jan 28 08:58:30 PST 2013
On Mon, 28 Jan 2013 08:20:23 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:
> One interesting fact is that we have evidence at hand. Optional parens
> _exist_ today in D, and have for a while. The language has worked. They
> haven't been a disaster.
I've seen some issues, but mostly for allowing normal functions as setters.
> Aside from discussions about @property itself, optional parens have just
> worked. We also have evidence that UFCS is convenient and useful. People
> use it and like it. And arguably UFCS and optional parens combine in a
> lovely way.
optional parens are something that has been difficult to argue against.
There is always the workaround of making your method names more verbose so
they aren't mistaken for properties.
> We've also converted the Phobos codebase to work with the half-strong
> -property switch. We've adorned a lot of functions with @property. I
> don't see evidence of found bugs or improved code quality.
> (Subjectively, I'd argue we actually degraded esthetics. There's no love
> lost between me and that "@property" plastered everywhere.)
the improvement of @property is all in the eye of the code reader. There
are no "bugs" or code quality improvements, the improvements are for the
sole benefit of reading the code, and defining the API. If something is a
@property, it should be accessed as a property. Being able to enforce
this results in cleaner and clearer code.
I've been doing mostly Objective C for the last 10 months. Interestingly
enough, objective C has a notion of @property that is quite similar to D.
You declare in the interface a property like:
@property(attributes) int value;
Where attributes can describe something about the property, is it atomic,
is it reference counted, etc.
What does this mean? It means there is a method for accessing value
implicitly declared as:
-(int) value; // translates to int value(); in D
If attributes does not include "readonly", it also means there is a method
for setting the value, implicitly declared as:
-(void) setValue:(int)val; // translates to void setValue(int val); in D
Now, note here that the @property declaration is COMPLETELY optional. One
can simply declare the two methods value and setValue:, and then Objective
C allows the syntax:
int x = obj.value; // translates in objective C to [obj value];, a.k.a.
obj.value(); in D
obj.value = x; // translates in objective C to [obj setValue:x];, a.k.a.
obj.setValue(x); in D
note that dot syntax is reserved strictly for property access in Obj-C,
field access is done via obj->field, and methods are done via [obj
method]. So the comparison to D must take into account that D uses .
notation for everything, making it a bit more confusing.
@property here serves two purposes. Since properties are the ONLY way to
publicly access class fields, it provides a very commonly-used boilerplate
generation. Second, with the given attributes, there is a corresponding
@synthesize directive in the implementation that will create a default
accessor and optional setter (assuming attributes does not include
"readonly") that do the right thing, depending on whether the value is
atomic, whether it needs it's reference count updated, etc.
But what is really interesting here is that like D's current
implementation, the getter looks the same as a property or a method -- and
this hasn't caused much confusion for the langauge. However, UNLIKE D,
the setter is unmistakable as a normal function when you use the method
form! [obj setValue:x] cannot be mistaken for something that doesn't set
a field.
I would be perfectly fine ONLY defining @property on setters, and getters
where the parentheses are confusing (i.e. getting a delegate/function
pointer/functor).
I would be fine with D CANCELLING @property as long as we had something
like Objective C, where the function form of a setter CANNOT be mistaken
for a normal function. In this case, we would have to live with delegate
properties requiring two sets of parentheses.
But if you get rid of @property and we are back to D1-style properties,
please acknowledge that the abuse of functions as setters is not a good
situation. I had "bugs" in prior D1 projects where a normal non-property
function was easily misinterpreted as a property, and I ended up having to
rename the function to something weird so it couldn't be mistaken as a
property. The nice thing about the objective-c solution is it puts the
burden of naming convention on the *property* function. With D1, the
burden is on *all* functions to broadcast "no, I'm not a property".
>
> These are not "what if" hypotheses; they describe experience accumulated
> from past events. Even people who dislike optional parens or UFCS must
> agree that their sentiment is far from widespread - unlike, for example,
> was the case for string lambdas.
These "past events" should be taken with a grain of salt, since @property
was never fully realized. In languages where properties were fully
enforced, it has not caused problems or undue headaches.
-Steve
More information about the Digitalmars-d
mailing list