Taking address of properties

Steven Schveighoffer schveiguy at yahoo.com
Fri Feb 8 12:13:07 PST 2013


On Fri, 08 Feb 2013 14:05:40 -0500, Robert <jfanatiker at gmx.at> wrote:

> On Fri, 2013-02-08 at 12:52 -0500, Steven Schveighoffer wrote:
>>
>> Then it doesn't conform to the range API, where front is a property.
> I can't find anything about that front has to be a property here:
> http://dlang.org/phobos/std_range.html#isInputRange
>
> all it states that you can get the current element by issuing:
> 	r.front
> which would still be possible with the optional parentheses of DIP23.

Technically this is true.  But the expectation is that r.front is a  
property/field, not a function.  That aspect is difficult to capture in a  
template, especially in the current implementation where @property on a  
getter is essentially redundant info.

In fact, the only case where a properly-implemented @property would be  
required on a getter is for delegate properties.  I would argue that if  
@property worked correctly, it would be possible and correct to require  
r.front to be a property in that template.

>>
>> > front for arrays would not be a property for two reasons:
>> > 1. front is a UFCS function, I think supporting UFCS with properties
>> is
>> > just getting it wrong, have a look at DIP 23 if you don't believe
>> me.
>>
>> I don't believe you.  DIP23 has flaws.  Care to explain?  "just
>> wrong"
>> isn't an explanation.
>
> Look at the section "No module-level properties". Why not?! That's a
> perfectly valid use of properties. The proposal disallows module-level
> properties, but instead allows:
> 	42.fun = 43;
> which reads like: assign 43 to the fun property of 42. We get this
> really obscure feature but disallowing module-level properties? If that
> is not wrong, than I don't know what is.

Module level properties pose an issue, because @property does not  
designate whether a property is a getter or a setter.  In particular, a  
single-arg property function could be considered both a module property  
setter, or a UFCS property getter.

So your issue is not really that UFCS properties are wrong, it's that  
disabling module-level properties is wrong.  I agree with you, but at the  
same time, module level properties are not as common or useful as UFCS.   
In fact, one could argue they are more confusing since module scope is one  
of the only scopes that can be obscured.

There are other possible solutions, such as designating something as a  
getter specifically, or adding more syntax (i.e. decorating the first  
parameter as 'this' for a module-level UFCS getter).  But for now, the  
easiest thing is to disallow one or the other, and since UFCS properties  
are pretty much essential in Phobos, he's disabling the module level  
properties.

The 42.fun = 43 example, just about everything is wrong with that.

Look here is another function that D "allows":

void increment(int x);

What is that exactly supposed to do?

42.increment(); // what?
increment(42); // what?

Design and naming of functions is never going to be a problem that the  
compiler can solve.

>>
>> > 2. My current version, would not allow properties to return ref, but
>> > instead a property is a property if it defines a getter or a setter
>> or
>> > both with the following exact definition:
>> >
>> >       @property void a(T val);
>> >       @property T a();
>>
>> This is a severe reduction in expression, we should not be looking
>> for
>> extra ways to invalidate existing code unless there is an extremely
>> good
>> reason.  "Just wrong" is not it.
>
> I have really good reasons and I hope I'll explain them well enough in
> the DIP I am currently writing. You already suggested that keeping
> compatibility to a broken implementation is not worth it, simply
> removing the @property in cases where there are no longer allowed, seems
> not too hard a change to me, especially if we agree that we have to
> break compatibility in one way or the other.

My point on that was, if something works but is not supposed to, we  
shouldn't have to worry about keeping that code working.  @property in its  
current form is NOT implemented as it was designed.  There is no  
requirement to keep existing behavior that doesn't correctly work.

In the example given, @property is supposed to ban the use of parentheses  
according to the spec, but it doesn't.  In fact, in the case of a  
@property that returns a delegate, it REQUIRES the extra parentheses.   
This is a bug, and not something to try and keep working.

On the other hand, ref @properties is NOT a bug, it functions as  
designed.  Whether to remove it or not is certainly a discussion we can  
have, but it's not buggy behavior.  See the difference?

-Steve


More information about the Digitalmars-d mailing list