January 28, 2013
On Monday, 28 January 2013 at 14:28:30 UTC, Maxim Fomin wrote:
> On Monday, 28 January 2013 at 14:09:20 UTC, Dicebot wrote:
>> On Monday, 28 January 2013 at 14:00:16 UTC, Maxim Fomin wrote:
>>> Returning void instead of int in the example break assignment chaining a = b = c. Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?
>>
>> It should not if evaluating the value of (b = c) will call getter for b.
>
> Why getter and not setter? Expression a = b = c = d should call getter for d and setter for rest of them. And if c setter returns void the chain breaks.

"a = b" calls setter
"(a = b)" calls setter first, getter second
"x = b = c" is same as "x = (b = c)" thus calls setter, then getter and then setter again

I don't know how it is done know, but that is quite logical C-like approach based on the fact that result of expression (a = b) is equal to a.
January 28, 2013
On Monday, 28 January 2013 at 14:38:19 UTC, Dicebot wrote:
> On Monday, 28 January 2013 at 14:28:30 UTC, Maxim Fomin wrote:
>> On Monday, 28 January 2013 at 14:09:20 UTC, Dicebot wrote:
>>> On Monday, 28 January 2013 at 14:00:16 UTC, Maxim Fomin wrote:
>>>> Returning void instead of int in the example break assignment chaining a = b = c. Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?
>>>
>>> It should not if evaluating the value of (b = c) will call getter for b.
>>
>> Why getter and not setter? Expression a = b = c = d should call getter for d and setter for rest of them. And if c setter returns void the chain breaks.
>
> "a = b" calls setter
> "(a = b)" calls setter first, getter second
> "x = b = c" is same as "x = (b = c)" thus calls setter, then getter and then setter again
>
> I don't know how it is done know, but that is quite logical C-like approach based on the fact that result of expression (a = b) is equal to a.

It is not that obvious, as the result of a = b is also equal to b.
January 28, 2013
On Monday, 28 January 2013 at 14:44:15 UTC, deadalnix wrote:
> It is not that obvious, as the result of a = b is also equal to b.

AFAIR it was defined strictly in C standard to be one two. Do not remember which one and do not have my trustful standard pdf nearby.
January 28, 2013
On Monday, 28 January 2013 at 14:38:19 UTC, Dicebot wrote:
> On Monday, 28 January 2013 at 14:28:30 UTC, Maxim Fomin wrote:
>> On Monday, 28 January 2013 at 14:09:20 UTC, Dicebot wrote:
>>> On Monday, 28 January 2013 at 14:00:16 UTC, Maxim Fomin wrote:
>>>> Returning void instead of int in the example break assignment chaining a = b = c. Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?
>>>
>>> It should not if evaluating the value of (b = c) will call getter for b.
>>
>> Why getter and not setter? Expression a = b = c = d should call getter for d and setter for rest of them. And if c setter returns void the chain breaks.
>
> "a = b" calls setter

Agree.

> "(a = b)" calls setter first, getter second

How it can call setter for a if b is not evaluated? This expression is rewritten to setter function call with argument that getter provides.

> "x = b = c" is same as "x = (b = c)" thus calls setter, then getter and then setter again

It should be rewritten to a.setter(b.setter(c.getter()))

> I don't know how it is done know, but that is quite logical C-like approach based on the fact that result of expression (a = b) is equal to a.

Yes, that is why if setter for "a" defaults to void and not to typeof(b) assignment chaining is broken.
January 28, 2013
On Monday, 28 January 2013 at 15:05:21 UTC, Maxim Fomin wrote:
> On Monday, 28 January 2013 at 14:38:19 UTC, Dicebot wrote:
>> On Monday, 28 January 2013 at 14:28:30 UTC, Maxim Fomin wrote:
>>> On Monday, 28 January 2013 at 14:09:20 UTC, Dicebot wrote:
>>>> On Monday, 28 January 2013 at 14:00:16 UTC, Maxim Fomin wrote:
>>>>> Returning void instead of int in the example break assignment chaining a = b = c. Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?
>>>>
>>>> It should not if evaluating the value of (b = c) will call getter for b.
>>>
>>> Why getter and not setter? Expression a = b = c = d should call getter for d and setter for rest of them. And if c setter returns void the chain breaks.
>>
>> "a = b" calls setter
>
> Agree.
>

Correction: assuming b is a variable, not property.
January 28, 2013
On Monday, 28 January 2013 at 15:05:21 UTC, Maxim Fomin wrote:
> It should be rewritten to a.setter(b.setter(c.getter()))
That is exactly the problem. "a = b = c" should be rewritten as:
b.set(c.get());
a.set(b.get()); // or a.set(c.get()); do not remember C rules
January 28, 2013
They don't. If you want such behaviour, you would write your own setter getter, with @property attribute, just like you do now.

Best regards,

Robert

On Mon, 2013-01-28 at 15:00 +0100, Maxim Fomin wrote:
> Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?


January 28, 2013
On Mon, 28 Jan 2013 09:00:15 -0500, Maxim Fomin <maxim@maxim-fomin.ru> wrote:

> On Monday, 28 January 2013 at 12:31:35 UTC, Jacob Carlborg wrote:
>> On 2013-01-28 12:44, Robert wrote:
>>> Having the compiler lower the following:
>>>
>>> @property int a;
>>>
>>> to
>>>
>>> private int __a;
>>>
>>> @property int a() {
>>> return __a;
>>> }
>>> @property int a(int new_a) {
>>>   __a=new_a;
>>>   return __a;
>>> }

This can be done without compiler help.  But we need @property as a primitive to allow it.

>> I would love that. But the setter should return void and the compiler should to property rewrites.
>
> Returning void instead of int in the example break assignment chaining a = b = c. Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?

I think Jacob's point is that a = b = c would lower to:

b = c;
a = b;

But I think it would be wasteful in the given case.  __a is already in the register, I think actually the return __a is a noop.

In other cases, where the property value may be a large struct or whatnot, not returning the new value from a setter would make sense.

It would be nice if the compiler made the right choice depending on whether you returned a value from the property or not.

-Steve
January 28, 2013
On Monday, 28 January 2013 at 15:31:48 UTC, Dicebot wrote:
> On Monday, 28 January 2013 at 15:05:21 UTC, Maxim Fomin wrote:
>> It should be rewritten to a.setter(b.setter(c.getter()))
> That is exactly the problem. "a = b = c" should be rewritten as:
> b.set(c.get());
> a.set(b.get()); // or a.set(c.get()); do not remember C rules

From ISO C Assignment operators chapter: "An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment,111) but is not an lvalue. The type of an assignment expression is the type the left operand would have after lvalue conversion. The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.".

So, in right-associative expression a = b = c, at first subexpression b = c is evaluated to b.set(c.get). Than value of this expression (note, that evaluated expression is not b, it is b = c) is assigned to a. How it can be done if b.set() returns void? Than expression a =  (b = c) is evaluated to a.set( b = c) which is (a.setter(b.setter(c.getter))

b.setter cannot be called prior to b.getter as in your example #1 due to sequence rules. The example #2 would be for expression a = c, b = c which is not a = b = c in the presence of properties.
January 28, 2013
On Monday, 28 January 2013 at 16:50:37 UTC, Maxim Fomin wrote:
> Than value of this expression (note, that evaluated expression is not b, it is b = c) is assigned to a.

Quoting you (that was exactly part of standard I was referring too):
"assignment expression has the value of the left operand"

Left operand for (b = c) is b. Thus (b = c) has value of b. Value of b is b.getter(). Thus compiler is re-writing it wrong if we copy C rules.

> b.setter cannot be called prior to b.getter as in your example #1 due to sequence rules. The example #2 would be for expression a = c, b = c which is not a = b = c in the presence of properties.

What sequence rules are you speaking about?