October 09, 2010
On 10/9/10 13:33 CDT, Steven Schveighoffer wrote:
> On Fri, 08 Oct 2010 16:56:14 -0400, Nick Sabalausky <a@a.a> wrote:
>
>>
>> Ugh, it seems D still doesn't quite understand the concept of a property.
>> Here:
>>
>> @property int foo() // Obviously getter
>> @property void foo(int x) // Obviously setter
>>
>> No other form makes any sence as a property. Frankly, I'm very surprised,
>> and dissapointed, that anything else is even allowed. The only *possible*
>> exception being:
>>
>> @property int foo(int x) // Combined getter/setter, if we decide that's
>> needed
>>
>> It doesn't make any sense for a property getter to have a parameter
>> (unless
>> it's one parameter and it's used to set a new value). And it doesn't make
>> any sence for a setter to have anthing other than exactly one parameter.
>> Just disallow it. What could possibly be the point anyway? If it's got
>> parameters it's a function call, not a variable.
>
> Property setters can have two parameters, one is the item used to set
> it, and one is the rvalue to use when setting. In objects, the first
> parameter is the hidden this parameter. With UFC, the parameter is
> explicit. Unless you feel builtin arrays should never have properties?
>
> The only exception are global properties which are not set on anything.
> And this is the problem.
>
> I think the syntax discussed in the other part of this thread is
> probably a good way to disambiguate the issues.
>
> -Steve

One possibility is to simply say that

@property int foo(T x);

always means a getter for T. This is because if you want to define a global with getter and setter you can always write a type with assignment and alias this.


Andrei
October 09, 2010
On 10/9/10 13:33 CDT, Steven Schveighoffer wrote:
> On Fri, 08 Oct 2010 16:56:14 -0400, Nick Sabalausky <a@a.a> wrote:
>
>>
>> Ugh, it seems D still doesn't quite understand the concept of a property.
>> Here:
>>
>> @property int foo() // Obviously getter
>> @property void foo(int x) // Obviously setter
>>
>> No other form makes any sence as a property. Frankly, I'm very surprised,
>> and dissapointed, that anything else is even allowed. The only *possible*
>> exception being:
>>
>> @property int foo(int x) // Combined getter/setter, if we decide that's
>> needed
>>
>> It doesn't make any sense for a property getter to have a parameter
>> (unless
>> it's one parameter and it's used to set a new value). And it doesn't make
>> any sence for a setter to have anthing other than exactly one parameter.
>> Just disallow it. What could possibly be the point anyway? If it's got
>> parameters it's a function call, not a variable.
>
> Property setters can have two parameters, one is the item used to set
> it, and one is the rvalue to use when setting. In objects, the first
> parameter is the hidden this parameter. With UFC, the parameter is
> explicit. Unless you feel builtin arrays should never have properties?
>
> The only exception are global properties which are not set on anything.
> And this is the problem.
>
> I think the syntax discussed in the other part of this thread is
> probably a good way to disambiguate the issues.
>
> -Steve

One possibility is to simply say that

@property int foo(T x);

always means a getter for T. This is because if you want to define a global with getter and setter you can always write a type with assignment and alias this.


Andrei
October 09, 2010
On Sat, 09 Oct 2010 23:37:51 +0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 10/9/10 13:33 CDT, Steven Schveighoffer wrote:
>> On Fri, 08 Oct 2010 16:56:14 -0400, Nick Sabalausky <a@a.a> wrote:
>>
>>>
>>> Ugh, it seems D still doesn't quite understand the concept of a property.
>>> Here:
>>>
>>> @property int foo() // Obviously getter
>>> @property void foo(int x) // Obviously setter
>>>
>>> No other form makes any sence as a property. Frankly, I'm very surprised,
>>> and dissapointed, that anything else is even allowed. The only *possible*
>>> exception being:
>>>
>>> @property int foo(int x) // Combined getter/setter, if we decide that's
>>> needed
>>>
>>> It doesn't make any sense for a property getter to have a parameter
>>> (unless
>>> it's one parameter and it's used to set a new value). And it doesn't make
>>> any sence for a setter to have anthing other than exactly one parameter.
>>> Just disallow it. What could possibly be the point anyway? If it's got
>>> parameters it's a function call, not a variable.
>>
>> Property setters can have two parameters, one is the item used to set
>> it, and one is the rvalue to use when setting. In objects, the first
>> parameter is the hidden this parameter. With UFC, the parameter is
>> explicit. Unless you feel builtin arrays should never have properties?
>>
>> The only exception are global properties which are not set on anything.
>> And this is the problem.
>>
>> I think the syntax discussed in the other part of this thread is
>> probably a good way to disambiguate the issues.
>>
>> -Steve
>
> One possibility is to simply say that
>
> @property int foo(T x);
>
> always means a getter for T. This is because if you want to define a global with getter and setter you can always write a type with assignment and alias this.
>
>
> Andrei

I respectfully disagree. I strongly believe writing getters and setters should be a) consistent with each other and b) consistent with class/struct properties.
October 09, 2010
Andrei Alexandrescu <SeeWebsiteForEmail@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".
October 09, 2010
On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean@invisibleduck.org> wrote:

> Andrei Alexandrescu <SeeWebsiteForEmail@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.
October 10, 2010
On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden@gmail.com> wrote:

> On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean@invisibleduck.org> wrote:
>
>> Andrei Alexandrescu <SeeWebsiteForEmail@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?
October 10, 2010
On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford@jhu.edu> wrote:

> On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden@gmail.com> wrote:
>
>> On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean@invisibleduck.org> wrote:
>>
>>> Andrei Alexandrescu <SeeWebsiteForEmail@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.
October 10, 2010
On Sat, 09 Oct 2010 22:03:56 -0400, Denis Koroskin <2korden@gmail.com> wrote:

> On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford@jhu.edu> wrote:
>
>> On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden@gmail.com> wrote:
>>
>>> On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean@invisibleduck.org> wrote:
>>>
>>>> Andrei Alexandrescu <SeeWebsiteForEmail@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)));
October 10, 2010
On Sun, 10 Oct 2010 08:44:59 +0400, Robert Jacques <sandford@jhu.edu> wrote:

> On Sat, 09 Oct 2010 22:03:56 -0400, Denis Koroskin <2korden@gmail.com> wrote:
>
>> On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford@jhu.edu> wrote:
>>
>>> On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden@gmail.com> wrote:
>>>
>>>> On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean@invisibleduck.org> wrote:
>>>>
>>>>> Andrei Alexandrescu <SeeWebsiteForEmail@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. 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.
October 10, 2010
On Sun, 10 Oct 2010 00:58:39 -0400, Denis Koroskin <2korden@gmail.com> wrote:

> On Sun, 10 Oct 2010 08:44:59 +0400, Robert Jacques <sandford@jhu.edu> wrote:
>
>> On Sat, 09 Oct 2010 22:03:56 -0400, Denis Koroskin <2korden@gmail.com> wrote:
>>
>>> On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford@jhu.edu> wrote:
>>>
>>>> On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden@gmail.com> wrote:
>>>>
>>>>> On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean@invisibleduck.org> wrote:
>>>>>
>>>>>> Andrei Alexandrescu <SeeWebsiteForEmail@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?