Uniform Function Call syntax for properties

Robert Jacques sandford at jhu.edu
Sun Oct 10 00:16:46 PDT 2010


On Sun, 10 Oct 2010 00:58:39 -0400, Denis Koroskin <2korden at gmail.com>  
wrote:

> On Sun, 10 Oct 2010 08:44:59 +0400, Robert Jacques <sandford at jhu.edu>  
> wrote:
>
>> On Sat, 09 Oct 2010 22:03:56 -0400, Denis Koroskin <2korden at gmail.com>  
>> wrote:
>>
>>> On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford at jhu.edu>  
>>> wrote:
>>>
>>>> On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin  
>>>> <2korden at gmail.com> wrote:
>>>>
>>>>> On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly  
>>>>> <sean at invisibleduck.org> wrote:
>>>>>
>>>>>> Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
>>>>>>> On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:
>>>>>>>> Someone was asking about UFC syntax for properties on d.learn,  
>>>>>>>> and I
>>>>>>>> realized, we have a huge ambiguity here.
>>>>>>>>
>>>>>>>> Given a function:
>>>>>>>>
>>>>>>>> @property int foo(int x)
>>>>>>>>
>>>>>>>> Is this a global setter or a getter on an int?
>>>>>>>
>>>>>>> Good question.
>>>>>>
>>>>>> Setter. Consider "a = b = c".
>>>>>
>>>>> I think you missed the point. Which of the two is it:
>>>>>
>>>>> int x = 42;
>>>>> auto y = x.foo(); // transformed into "auto y = foo(x);", getter
>>>>>
>>>>> or
>>>>>
>>>>> foo = 42; // transformed into "foo(42);", setter
>>>>>
>>>>> Both match.
>>>>
>>>> I agree that there is ambiguity here, but does it why does foo have  
>>>> to be only a getter or only a setter? Why can't it behave like  
>>>> either, depending on its implementation and use?
>>>
>>> Because you may want to have both, but you can't because their syntax  
>>> overlap.
>>
>> Okay I'm confused. How do their syntax overlap? And which syntaxes do  
>> you think are overlapping?
>> All the following 'lowerings' look fine/unambiguous to me:
>>
>> foo = 42; => foo(42);
>> y = x.foo; => y = x.foo(); => y = foo(x);
>> foo = foo = x.foo; => foo = foo = x.foo(); => foo = foo = foo(x); =>  
>> foo = foo(foo(x)); => foo(foo(foo(x)));
>
> I wasn't talking about ambiguity. I told that you can't assign different  
> behavior to
>
> foo = 42;
>
> and
>
> y = x.foo;
>
> Both are resolving to the same symbol.
>
> E.g. I'd like to write a setter, "foo = 42;":
>
> private int _foo;
> int foo(int x)
> {
>      debug writeln("foo = ", x);
>      _foo = x;
>      return x;
> }
>
> But the following code also triggers the setter above:
>
> y = 42.foo(); // prints "foo = 42;", sets private variable _foo to 42,  
> and returns that value
>
> That's completely unexpected.

Actually, that's completely expected, in my humble opinion. Yes, it will  
be a bit confusing to people new to D, perhaps even to those familiar with  
C#'s extension methods. But once one understands the power and freedom of  
UFC, that behavior is perfectly natural.

> Imagine yourself writing class Foo with method bar, and a user who  
> highjacks a hole in the language, creates class bar, and invokes method  
> Foo on it. That's what it looks like at this moment.

Well, hijacking won't be possible since D's got really good function  
hijacking detection. Also, how can Foo be both a method and a class?


More information about the Digitalmars-d mailing list