assignment: left-to-right or right-to-left evaluation?
Nick Sabalausky
a at a.a
Sat May 9 13:14:02 PDT 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail at erdani.org> wrote in message
news:gu4bqu$bq$1 at digitalmars.com...
> Consider:
>
> uint fun();
> int gun();
> ...
> int[] a = new int[5];
> a[fun] = gun;
>
> Which should be evaluated first, fun() or gun()? It's a rather arbitrary
> decision. C/C++ don't even define an order. Python chooses left-to-right,
> EXCEPT for assignment, which is right-hand side first. Lisp and C# choose
> consistent left-to-right. I don't like exceptions and I'd like everything
> to be left-to-right. However, this leads to some odd cases. Consider this
> example in TDPL:
>
This may sound strange coming from me, but I think I actually like the
Python way of doing it. I may be getting slightly ahead of myself by saying
this, but I think the inconsistency lies more with the assignment statement
itself than function evaluation order.
First of all:
lvalue = expression;
Anyone with any real experience in imperative programing looks at that and
sees "expression (on the right) gets evaluated, and then the result gets
placed into lvalue (on the left)". If both sides contain a function call,
and the functions in the lvalue get exaluated first, then that would seem to
contradict the intuitive understanding of the assignment's natural
right-to-left order.
I might be venturing slightly offtopic here, but lately, I've been giving a
bit of thought to matters of left/right directions. Consider the following:
fooA(); fooB(); fooC();
Flow of execution can be followed left-to-right. Which makes sense, because
most of the more common (human) languages are left-to-right. But then
there's:
lvalue = fooC(fooB(fooA(stuff)))
Now all of a sudden, it's all completely reversed! If you want to follow
this statement's flow-of-execution step-by-step, the entire thing goes
right-to-left: First stuff is evaluated, then fooA is called, then fooB is
called, then fooC is called, then a value gets assigned to lvalue. Of
course, function chaining syntax has been gaining popularity, so in *some*
cases you may be able to fix the ordering of the right-hand-side:
lvalue = stuff.fooA().fooB().fooC();
(Which, of course, also has the side-benefit of reducing parenthesis-hell).
Now, at least the right-hand-side, reads completely in a natural
left-to-right order.
However, there are languages out there that flip the assignment:
auto num;
5 => num;
I've never actually liked that in the past. I literally grew up using
ApplesoftBASIC and QBASIC, which use the more common "target_var =
expression" syntax, so the few times I came across the above, it always felt
awkward and uncomfortable. But lately, because of all of this, I've been
starting to think "expr => target_var" does have its merits. Of course, the
downside is one could argue that "lvalue = fooC(fooB(fooA(stuff)))" reads in
order from "general overview" to "more specific", and with
"stuff.fooA().fooB().fooC() => target_var;" you have to go all the way to
the end to see the general idea of what's finally gotten accomplished.
The reason I bring all this up is because that (not that it's likely to
actually happen in D) would allow the sensible Python-style of "functions in
the expression get evaluated before functions on the assignment-side"
*without* making any exceptions to the left-to-right rule (which, as I
pointed out before, is really more of an exception with the basic assignment
syntax).
More information about the Digitalmars-d
mailing list