DIP23 draft: Fixing properties redux

Steven Schveighoffer schveiguy at yahoo.com
Sun Feb 3 08:28:52 PST 2013


On Sun, 03 Feb 2013 11:11:05 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 2/3/13 5:14 AM, Johannes Pfau wrote:
>> "If a function returns a reference, then assignment through the
>> paren-less call should work: "
>>
>> This is the only part where I would disagree. Why is this special rule
>> necessary if we have full @property support? I think this would still
>> allow too many false positives.
>
> (As a note, this is the current behavior.)
>
> The way I see it is this is a natural consequence of optional parens.  
> The name of a function without a "&" prepended or a "()" after it will  
> invoke the function, and that's that.
>
>> One important aspect that this proposal doesn't cover yet is whether we
>> want to allow "semantic rewriting" for properties:
>> ----
>> Struct a;
>> a.property++; //would this be legal?
>> ----
>
> It's dangerous to get too clever about that. Anyhow, such rewrites are  
> possible:
>
> ++a.p ----> { auto v = a.p; ++v; a.p = v; return v; }()
> a.p++ ----> { auto v = a.p; ++a.p; return v; }()
>
> and so on.
>
>> for other corner cases this list is a good start:
>> http://wiki.dlang.org/Property_Discussion_Wrap-up#Implementation_concerns
>>
>> * Can we get a reference to the property? What does
>>    &x.property mean?
>
> We need to add this to the proposal. There are two schools of thought  
> here:
>
> 1. Make properties emulate regular variables as much as possible. In  
> that case &a.p is the same as &(a.p), i.e. it applies to the returned  
> value. (One counter-argument here is that properties should seldom  
> return a reference because that breaks encapsulation.)
>
> 2. Allow people to do whatever they need to do without much aggravation.  
> In that case &a.p obeys the normal rules of taking a method's address,  
> and &(a.p) applies to the returned value.
>
> I favor (2) and put it in http://wiki.dlang.org/DIP23. Will talk to  
> Walter.

This sounds good.  It might be a bit confusing, but nice in the fact that  
&(a.b) always means address of whatever b returns, whether it is a field  
or property.

>> * Are UFCS properties possible? How do they work exactly?
>> * How do you disambiguate property functions when they're free
>>    functions which conflict?
>
> I think it would be best to simply disallow parameterless module-level  
> properties.
>
> // at top level
> @property int foo(); // error
> @property int goo(int); // fine, assume a getter for int

I think this is a possible solution, and I can live with that, I'm fairly  
certain that some people use global properties currently, so they will not  
be too happy.

But having to set global properties using a function call (global getters  
can simply be paren-less functions) isn't horrible.

>> * Are templated properties allowed?
>> ** The access syntax for properties doesn't allow providing types
>
> No. Templated member variables are not allowed either.

Wait, what?  I don't like this idea.  Why should this not be allowed:

@property void x(T)(T t) {_x = to!(typeof(_x))(t);}

As for templates that return a templated type, it should be allowed,  
although the calling syntax would have to be for the explicit template  
call, since you can't do IFTI on return values.  In other words:

template x(T) { @property T x(){return to!(T)(_x);} }  // could be  
shortened to normal @property T x(T)()

auto xcopy = obj.x!(string).x;

Certainly, we need templated getters and setters at module levels:

@property T front(T)(T[] r) { return r[0];}

-Steve


More information about the Digitalmars-d mailing list