suggestion for eliminating the overload ambiguity for properties

Kirk McDonald kirklin.mcdonald at gmail.com
Sun Jul 29 23:01:31 PDT 2007


Reiner Pope wrote:
> Bill Baxter wrote:
>> Right now there's a problem in that if one uses property methods as 
>> suggested by the D reference manual:
>>
>> class Foo
>> {
>>   int prop() { ... }
>>   int prop(int x) { ... }
>> }
>>
>> then you can't reliably get a delegate to the setter.   &aFoo.prop 
>> gets you whichever appears first, which in this case is the getter.  
>> This is a known bug, and the most likely resolution for it will be to 
>> make trying to do this an error.
>>
>> So what if we just give D support for Java-style convention-based 
>> deduction of properties.  You can keep using properties as-is, but 
>> _if_ there's a method called 'set_prop' then it can be used as a 
>> setter property.  So the above could be written as:
>>
>> class Foo
>> {
>>   int prop() { ... }
>>   int set_prop(int x) { ... }
>> }
>>
>> This way you can still use your property syntax, but you can also 
>> easily distinguish the getter from the setter when taking a delegate.
> 
> I can see that being able to distinguish setter from getter is 
> important, and it would be nice not to require casting for that. But I 
> don't think that should be done in the language, because it doesn't 
> generalise to selecting overloads for non-property functions.
> 
> I thought that you could write a template which gets you the 
> getter/setter using __traits. In fact, I was right, and this turned out 
> to be one of the cleanest uses of traits I've found. I wrote two 
> templates called Getter and Setter, which will return the getter and 
> setter for your particular properties. For instance, if a class Foo has 
> a getter/setter pair, prop, you can write
> 
[snip]

Using __traits is not necessary. Pyd has long used this template (though 
perhaps __traits is cleaner):

template property_parts(alias p) {
     // This may be either the getter or the setter
     alias typeof(&p) p_t;
     alias ParameterTypeTuple!(p_t) Info;
     // This means it's the getter
     static if (Info.length == 0) {
         alias p_t getter_type;
         alias typeof(p(ReturnType!(p_t).init))
             function(ReturnType!(p_t)) setter_type;
     // This means it's the setter
     } else {
         alias p_t setter_type;
         alias Info[0] function() getter_type;
     }
}

It is assumed that the setter accepts as an argument the same type which 
the getter returns. Wrapping this with a prettier interface is left as 
an exercise for the reader. :-)

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org



More information about the Digitalmars-d mailing list