May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Georg Wrede | On Mon, 11 May 2009 09:37:56 -0400, Georg Wrede <georg.wrede@iki.fi> wrote:
> Steven Schveighoffer wrote:
>> For example:
>> mydic[x] = mydic[y] = mydic[z] = mydic.length;
>
>
> I distinctly remember Walter discouraging chained assignments in the doccs, already in the very early versions of D.
Seriously? So the correct method is to do this:
auto tmp = mydic.length;
mydic[x] = tmp;
mydic[y] = tmp;
mydic[z] = tmp;
???
That sucks. We have to remember, there are reasons why we stopped having to use assembly :)
-Steve
| |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Mon, May 11, 2009 at 11:07 AM, Steven Schveighoffer <schveiguy@yahoo.com> wrote: >>> mydic[x] = mydic[y] = mydic[z] = mydic.length; > auto tmp = mydic.length; > mydic[x] = tmp; > mydic[y] = tmp; > mydic[z] = tmp; > > ??? > > That sucks. We have to remember, there are reasons why we stopped having to use assembly :) Funny, I vastly prefer the latter to the former. Having more than one thing happen on one line is very difficult to read after having written it, for me. | |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | On Mon, 11 May 2009 11:26:36 -0400, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote: > On Mon, May 11, 2009 at 11:07 AM, Steven Schveighoffer > <schveiguy@yahoo.com> wrote: > >>>> mydic[x] = mydic[y] = mydic[z] = mydic.length; > >> auto tmp = mydic.length; >> mydic[x] = tmp; >> mydic[y] = tmp; >> mydic[z] = tmp; >> >> ??? >> >> That sucks. We have to remember, there are reasons why we stopped having to >> use assembly :) > > Funny, I vastly prefer the latter to the former. Having more than one > thing happen on one line is very difficult to read after having > written it, for me. So I take it if you have many function calls, or chained function calls, you split them out into separate lines? :P fun(gun(123)).xyz() => auto tmp1 = gun(123); auto tmp2 = fun(tmp1); tmp2.xyz(); ??? I look at chained assignment as no different. Even if order of operations was defined as left to right, I'd still prefer using this: auto tmp = mydic.length; mydic[x] = mydic[y] = mydic[z] = tmp; I use assignment chaining all the time in C# Forms when I'm disabling/enabling a set of controls. e.g.: checkBox1.Enabled = textField1.Enabled = textField2.Enabled = textField3.Enabled = true; It seems pretty straightforward to me... -Steve | |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu wrote:
> Georg Wrede wrote:
>> Andrei Alexandrescu wrote:
>>> Consider:
>>>
>>> uint fun();
>>> int gun();
>>> ...
>>> int[] a = new int[5];
>>> a[fun] = gun;
>>>
>>> Which should be evaluated first, fun() or gun()?
>>
>> arra[i] = arrb[i++];
>>
>> arra[i++] = arrb[i];
>>
>> I'm not sure that such dependences are good code.
>>
>> By stating a definite order between lvalue and rvalue, you would actually encourage this kind of code.
>
> By not stating it, I introduce a gratuitous nonportability.
If the programmer has introduced dependencies on the evaluation order, yes. But if he hasn't, then it will not introduce anything.
With
a[fun] = gun;
a rewrite
auto f = a[fun];
a[f] = gun;
makes it explicit how the programmer wants it done. It also removes any uncertainty (and need to remember an arbitrary rule) for other people.
If you'd really want things easy for Walter, unambiguous, and clear for the reader, then you'd advocate forbidding expressions in lvalues.
| |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Georg Wrede | Georg Wrede wrote: > If the programmer has introduced dependencies on the evaluation order, yes. But if he hasn't, then it will not introduce anything. If violations could be checked such that invalid code is rejected, your solution would work. > With > > a[fun] = gun; > > a rewrite > > auto f = a[fun]; > a[f] = gun; > > makes it explicit how the programmer wants it done. It also removes any uncertainty (and need to remember an arbitrary rule) for other people. > > If you'd really want things easy for Walter, unambiguous, and clear for the reader, then you'd advocate forbidding expressions in lvalues. I think that would be too restrictive. a[b] is already an expression. The solution is simple: define an order of evaluation such that even bad code behaves consistently. Andrei | |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu wrote: > Georg Wrede wrote: >> If the programmer has introduced dependencies on the evaluation order, yes. But if he hasn't, then it will not introduce anything. > > If violations could be checked such that invalid code is rejected, your solution would work. > >> With >> >> a[fun] = gun; >> >> a rewrite >> >> auto f = a[fun]; >> a[f] = gun; >> >> makes it explicit how the programmer wants it done. It also removes any uncertainty (and need to remember an arbitrary rule) for other people. >> >> If you'd really want things easy for Walter, unambiguous, and clear for the reader, then you'd advocate forbidding expressions in lvalues. > > I think that would be too restrictive. a[b] is already an expression. I guessed you'd say that. But I thought it'd be condescending to explain that the compiler should notice a leaf expression. > The solution is simple: define an order of evaluation such that even bad code behaves consistently. Then pick lexical order. For consistency, that's what statement.html has all over the place anyway. | |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:op.utrtl8x7eav7ka@steves.networkengines.com... > On Mon, 11 May 2009 09:37:56 -0400, Georg Wrede <georg.wrede@iki.fi> wrote: > >> Steven Schveighoffer wrote: >>> For example: >>> mydic[x] = mydic[y] = mydic[z] = mydic.length; >> >> >> I distinctly remember Walter discouraging chained assignments in the doccs, already in the very early versions of D. > > Seriously? So the correct method is to do this: > > auto tmp = mydic.length; > mydic[x] = tmp; > mydic[y] = tmp; > mydic[z] = tmp; > > ??? > > That sucks. We have to remember, there are reasons why we stopped having to use assembly :) > I was giving a little bit of thought to assignment chaining the other day. Unless someone can point out why I'm wrong, I think some of the functional-style stuff we've been getting into can make assignment chaining obsolete. Hypothetical example: [mydic[x], mydic[y], mydic[z]].fill(mydic.length); I think something like that would be more clear than both the "tmp" and assignment chaining versions, and perhaps allow any language complexities that arise from the assignment chaining feature to be removed. | |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | "Nick Sabalausky" <a@a.a> wrote in message news:gua0dm$121j$1@digitalmars.com... > > I was giving a little bit of thought to assignment chaining the other day. Unless someone can point out why I'm wrong, I think some of the functional-style stuff we've been getting into can make assignment chaining obsolete. > > Hypothetical example: > [mydic[x], mydic[y], mydic[z]].fill(mydic.length); Or maybe something like: [mydic[x], mydic[y], mydic[z]].each = mydic.length; > > I think something like that would be more clear than both the "tmp" and assignment chaining versions, and perhaps allow any language complexities that arise from the assignment chaining feature to be removed. | |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Nick Sabalausky wrote: > I was giving a little bit of thought to assignment chaining the other day. Unless someone can point out why I'm wrong, I think some of the functional-style stuff we've been getting into can make assignment chaining obsolete. > > Hypothetical example: > [mydic[x], mydic[y], mydic[z]].fill(mydic.length); > > I think something like that would be more clear than both the "tmp" and assignment chaining versions, and perhaps allow any language complexities that arise from the assignment chaining feature to be removed. Seriously? [mydic[x], mydic[y], mydic[z]].fill(mydic.length);, I admit, is not bad, but it's certainly not easier on the eyes than mydic[x] = mydic[y] = mydic[z] = mydic.length;. And you need a good optimizing compiler to get the same speed. Plus, doesn't it suffer from the same problems as the assignment-chaining version? If x, y and/or z are not already in mydic, which mydic.length are you using there? -- Michiel Helvensteijn | |||
May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michiel Helvensteijn | "Michiel Helvensteijn" <m.helvensteijn.remove@gmail.com> wrote in message news:gua0ub$130b$1@digitalmars.com... > Nick Sabalausky wrote: >> I was giving a little bit of thought to assignment chaining the other >> day. >> Unless someone can point out why I'm wrong, I think some of the >> functional-style stuff we've been getting into can make assignment >> chaining obsolete. >> >> Hypothetical example: >> [mydic[x], mydic[y], mydic[z]].fill(mydic.length); >> >> I think something like that would be more clear than both the "tmp" and assignment chaining versions, and perhaps allow any language complexities that arise from the assignment chaining feature to be removed. > > Seriously? > > [mydic[x], mydic[y], mydic[z]].fill(mydic.length);, > > I admit, is not bad, but it's certainly not easier on the eyes than > > mydic[x] = mydic[y] = mydic[z] = mydic.length;. > True, that's why I replied again and suggested something like: [mydic[x], mydic[y], mydic[z]].each = mydic.length; Although that might be more difficult to implement properly. > And you need a good optimizing compiler to get the same speed. True, although as our compilers progress that will hopefully become less and less of an issue. And in the meantime, if you really needed the speed, you could make a templated string mixin that does the "tmp" version: // Assuming we actually need the extra speed in this case: mixin(fill!([mydic[x], mydic[y], mydic[z]], mydic.length)); // (or something roughly like that) > Plus, doesn't > it suffer from the same problems as the assignment-chaining version? If x, > y and/or z are not already in mydic, which mydic.length are you using > there? > At least in the case of the ".fill()" version, the function-call syntax makes it clear that you're using the original "mydic.length". Other than that, I'm convinced that order-of-function-call for assignments should be rhs first, then lhs, regardless of what syntax is used to assign an rvalue to multiple lvalues. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply