On 2009-11-09, Tony A. [email protected] wrote:
[Note: parts of this message were removed to make it a legal post.]
On Sun, Nov 8, 2009 at 9:54 PM, Joel VanderWerf [email protected]wrote:
The only sane answer is to do what C does, as far as parsing.
You will find the answer to these edge cases varies.
No, you won’t. The parsing is 100% consistent and has been, so far as I
know, in every compiler released since the mid-70s.
Ruby is a pure expression-based language (and I see you acknowledge that
later in this message). There are no statements which don’t return a value.
But “expressions” can be extremely large.
In C, “x++” yields the current value of x, and at some point between the
prior sequence point and the next sequence point, x gets incremented.
The reason that “i + i++” is undefined behavior, not just an
unspecified
value, is that Deep Magic may occur to implement or support the
increment operators. There’s no particular guarantee – none at all –
that such code even runs, let alone does anything specific.
That’s fine. C has “sequence points”, and because expressions in C are
pretty simple and limited, you always have plenty. Consider:
for (i = 0; i < 10; ++i) {
printf(“%d\n”, i);
}
The evaluation of each of the control expressions in the for loop is
separated from everything else by sequence points. There’s a sequence
point
between the evaluation of i for the printf and the actual execution of
printf, and another when printf is done, and so on.
Let’s look at a while loop to simplify a bit:
i = 0;
while (i++ < 10) {
printf(“%d\n”, i);
}
In C, that should consistently yield the numbers 1 through 10. (When i
is 0, i++ is < 10, but increments i, so printf sees 1. When i is 9, i++
is 9, thus still < 10, but increments i, so printf sees 10.)
In Ruby, if you did something similar to this, you might write:
i = 0
while i++ < 10
puts i
end
When, exactly, do we expect that the increment happens? This whole
thing
is an expression. I’m not aware of anything particularly equivalent to
sequence points. Do we ensure that i is incremented before puts is
called?
Consider that this whole block (while … end) could be a single
argument
to a function, because it’s just an expression.
In short, the fact that control statements in Ruby are also expressions
makes it harder to run with the simple “by the end of the expression”
heuristic most people use.
Think about:
puts i++ || i
In C, you’d have a nice solid guarantee that the increment happens
before
the || (because &&/|| are sequence points). Would you in Ruby? I have
no
clue.
Correct, it’s ++x that would have the same effect as x += 1, not that I find
the preincrementation vs postincrementation distinction particularly useful
in Ruby, which is why I’ve advocated picking the canonical one and going
with that, even though preincrementation has semantics which would make more
sense in Ruby.
There’s nothing particularly more canonical about postincrement. It is
the one that’s harder to replace by just writing something else. I
would
rather see both, personally. In particular, it looks very much as
though
postincrement would be expensive, so I’d want preincrement available so
I could actually use it. 
-s