May 11, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | On Mon, 11 May 2009 16:03:39 -0400, 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. This is close to what we are going to do for the Euphoria language. Currently, Euphoria does not allow assignment chaining (an assignment is not an expression) so the proposed syntax is ... (mydic[x], mydic[y], mydic[z]) = length(mydic) Plus that language evaluates the source expression before tackling the target expression, so your idea is not unheared of. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell | |||
May 12, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Nick Sabalausky wrote: > True, that's why I replied again and suggested something like: > > [mydic[x], mydic[y], mydic[z]].each = mydic.length; [[mydic[x], mydic[y], mydic[z]].each].each = mydic.length; [[[mydic[x], mydic[y], mydic[z]].each].each].each = mydic.length; [[[[mydic[x], mydic[y], mydic[z]].each].each].each].each = mydic.length; ... What's wrong with assignment chaining? I'm amazed anybody would find chained assignment more confusing than unchained assignment. -- Rainer Deyke - rainerd@eldwood.com | |||
May 12, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Rainer Deyke | "Rainer Deyke" <rainerd@eldwood.com> wrote in message news:guamfi$2b0d$1@digitalmars.com... > Nick Sabalausky wrote: >> True, that's why I replied again and suggested something like: >> >> [mydic[x], mydic[y], mydic[z]].each = mydic.length; > > [[mydic[x], mydic[y], mydic[z]].each].each = mydic.length; > [[[mydic[x], mydic[y], mydic[z]].each].each].each = mydic.length; > [[[[mydic[x], mydic[y], mydic[z]].each].each].each].each = mydic.length; > ... > I'm not sure what point you're trying to make here, but my idea is that "each" would basically be a write-only "extension property" (to borrow C# terminology) of array. So "each" wouldn't have a getter or a return value and therefore trying to stick its non-existant read/return value into an array literal (as you're doing above) would be an error. > > What's wrong with assignment chaining? I'm amazed anybody would find chained assignment more confusing than unchained assignment. > I never said I had any problem with assignment chaining. I find them very straightforward (provided that their function-evaluation order is "rhs first, then lhs"). I'm just saying that if there's compelling reason to say "ok, assignments shouldn't be expressions", for the sake of simplifying certain aspects of the language, and would therefore be giving up assignment-chaining, then we wouldn't have to resort to temp-var and non-DRY methods to assign a single value to multiple targets. ...I suppose I was getting a little farther off-topic than I thought I was, maybe that's where the confusion came from. | |||
May 12, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Nick Sabalausky wrote: > "Rainer Deyke" <rainerd@eldwood.com> wrote in message news:guamfi$2b0d$1@digitalmars.com... >> [[mydic[x], mydic[y], mydic[z]].each].each = mydic.length; ... >> > > I'm not sure what point you're trying to make here, but my idea is that "each" would basically be a write-only "extension property" (to borrow C# terminology) of array. So "each" wouldn't have a getter or a return value and therefore trying to stick its non-existant read/return value into an array literal (as you're doing above) would be an error. I had assumed that there was some sort of magic going on that would allow this. If '[mydic[x], mydic[y], mydic[z]].each' is a write-only property of an array, then assigning to it will modify the array, but leave 'mydic' untouched. -- Rainer Deyke - rainerd@eldwood.com | |||
May 12, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Mon, May 11, 2009 at 11:34 AM, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>> 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.
No. Nested function calls are incredibly common and do not (usually!) have side effects; it's not very different from other algebraic expressions. Chained method calls are still fairly common. It's incredibly rare that I have to assign the same value to multiple targets, and when I do, the little time I could save by not typing the second assignment is offset by the increased time it takes me to look for assignments to a variable when I come back to the code later.
It's much more of an argument of my brain not being trained to parse it due to its low incidence than anything else :P
| |||
May 12, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > It's > incredibly rare that I have to assign the same value to multiple > targets, and when I do, the little time I could save by not typing the > second assignment is offset by the increased time it takes me to look > for assignments to a variable when I come back to the code later. It's not about time. It's about code duplication. -- Michiel Helvensteijn | |||
May 12, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Rainer Deyke | "Rainer Deyke" <rainerd@eldwood.com> wrote in message news:guatj2$2pft$1@digitalmars.com... > Nick Sabalausky wrote: >> "Rainer Deyke" <rainerd@eldwood.com> wrote in message news:guamfi$2b0d$1@digitalmars.com... >>> [[mydic[x], mydic[y], mydic[z]].each].each = mydic.length; ... >>> >> >> I'm not sure what point you're trying to make here, but my idea is that "each" would basically be a write-only "extension property" (to borrow C# terminology) of array. So "each" wouldn't have a getter or a return value and therefore trying to stick its non-existant read/return value into an array literal (as you're doing above) would be an error. > > I had assumed that there was some sort of magic going on that would allow this. If '[mydic[x], mydic[y], mydic[z]].each' is a write-only property of an array, then assigning to it will modify the array, but leave 'mydic' untouched. > I wrote up a short app to try to think my idea through a bit better. This is the best I was able to get in D1: ------------------------- import tango.io.Stdout; void each(T, V)(T*[] array, V val) { foreach(T* elem; array) *elem = val; } void main() { int x, y, z; [&x, &y, &z].each(7); // Output: 7 7 7 Stdout.formatln("{} {} {}", x, y, z); } ------------------------- As you can see, it's not quite was I was trying to get. Things that would probably need to be changed to get what I really want: - Some sort of variable reference tuple (not a type tuple like we have now), so we could get rid of the pointer stuff, ie: Change "each([&x, &y, &z], 7);" to something like "each((x, y, z), 7);" - A *real* extention method syntax and a *real* property syntax, like in C#, plus the ablity to combine them, so then we could do: ------------------------- import tango.io.Stdout; // The "this" indicates it's an extension of T[] // and therefore can be called with // tuple.each instead of each(tuple) T each(T, V)(this T() tuple) { // set{}, so this is a hypothetical "extension property" // instead of an extention method. set(V val) { foreach(ref T elem; tuple) elem = val; } } void main() { int x, y, z; // Notice that the "xxx.each()" and "each = yyy" // syntaxes no longer conflict with each other. (x, y, z).each = 7; // Output: 7 7 7 Stdout.formatln("{} {} {}", x, y, z); } ------------------------- | |||
May 12, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michiel Helvensteijn | Michiel Helvensteijn wrote:
> Jarrett Billingsley wrote:
>
>> It's
>> incredibly rare that I have to assign the same value to multiple
>> targets, and when I do, the little time I could save by not typing the
>> second assignment is offset by the increased time it takes me to look
>> for assignments to a variable when I come back to the code later.
>
> It's not about time. It's about code duplication.
>
Code duplication is only an issue when it can be a maintenance problem. Repeating the name of a temporary variable in five consecutive assignments is not a maintenance problem.
A preference for or against assignment chaining is mainly stylistic. The exception is when you reference the same variables in the LHS as the RHS and modify them in one of the locations -- this gets confusing, even with a specified order.
For that reason, I always use the ++ and -- operators as statements. Other people can use them as expressions and not get confused, but I always have to take a moment to think about which value will get returned. It only takes a moment, but I prefer not having to spend thought on such trivial matters when I'm reading code.
| |||
May 12, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Sat, 09 May 2009 11:43:09 -0500, Andrei Alexandrescu wrote:
> If we want to get rid of newID, we'd write:
>
> writeln(dic.length, '\t', word);
> dic[word] = dic.length;
>
> by the Python rule, and
>
> writeln(dic.length, '\t', word);
> dic[word] = dic.length - 1;
>
> by the C# rule.
>
> What's best?
>
>
> Andrei
Looking at it, I don't see dic[word] as increasing the length. Nothing has been added yet so why would it change? Ok, I realize a new location in memory has be reserved for storing a value, but at a glance it doesn't appear as though it is happening. You would also leave off the -1 if 'word' was already in there.
| |||
June 22, 2009 Re: assignment: left-to-right or right-to-left evaluation? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Sat, 09 May 2009 11:43:09 -0500, Andrei Alexandrescu wrote:
> If we want to get rid of newID, we'd write:
>
> writeln(dic.length, '\t', word);
> dic[word] = dic.length;
>
> by the Python rule, and
>
> writeln(dic.length, '\t', word);
> dic[word] = dic.length - 1;
>
> by the C# rule.
>
> What's best?
If you use the Python rule you can rewrite
dic[word] = dic.length;
as
dic.opIndexAssign(word, dic.length);
By the C# rule you cannot do without opIndexForAssignment sort of thing. It's not a matter of best/worse IMO, it's a matter of feasible/not feasible.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply