Two comments, in addition to what have already been said in earlier threads.
First, it is not obvious that left-to-right evaluation inside an expression is natural. People commonly consider that, if your program depends on the order in which things are evaluated, then you should sequence it explicitly. You might call this a circular argument though: if the order of evaluation of arguments was specified, then using it would arguably qualify as “explicit sequencing”. However:
- it is debatable how explicit or unintentional it actually is, compared to e.g.
let x = e1 in e2
; - using sub-expressions that both compute a value and perform a side effect is often regarded as unnatural and bad style: functional or imperative, you should pick one.
Second, enforcing an order has a run-time cost, and since the language already features a way to sequence evaluation, there is no absolute need for that additional cost. As a matter of fact, while Python and Java indeed guarantee a strict left-to-right evaluation (and pay the cost for it), C leaves is unspecified, and right-to-left does happen in practice. I do not know how systematic it is but, for one, this C code compiled with gcc
:
#include <stdio.h>
int main (void)
{
printf(
"1st = %i, 2nd = %i\n",
(printf("evaluating 1st argument\n"), 1) ,
(printf("evaluating 2nd argument\n"), 2)
);
}
gives me:
evaluating 2nd argument
evaluating 1st argument
1st = 1, 2nd = 2
As I understand it, the reason is the same as in OCaml (which inherits from the ZINC machine, as mentioned): due to the way arguments are passed to functions through the stack, right-to-left evaluation is much easier and more efficient to compile.
Python and Java, being higher-level languages, focus a bit less on performance and a bit more on having a straightforward, tightly-specified semantics.