But that would make rules for other calculations involving pointers
and integers quite a bit more hairy to learn - I sometimes find my-
self having to subtract two pointers and adding integers, e.g. in
order to figure out a certain offset into an array, and then you
would have to take care to write
end_ptr - mid_ptr - j + i
or at least
( end_ptr - j ) - ( mid_ptr - i )
but probably not
end_ptr - j - mid_ptr + i
since the compiler would be entitled to evaluate "j - mid_ptr"
first.
No, it wouldn't. The optimizer is allowed to do whatever it likes,
but it always has to obey the basic parsing rules of the language.
Precedence says the above expression is invariably parsed as
(((end_ptr - j) - mid_ptr) + i)
---that is, (((ptr-int)-ptr)+int) ==> ((ptr-ptr)+int) ==> (int+int)
==> int.
[Drifting OT...]
Or it would make the rules for writing the compiler more
difficult, requiring the introduction of some kind of first and
second class types of addition and subtraction operators. I don't
think that it would be worth the additional troubles.
Again, it wouldn't, really. In fact, unless the compiler was written
using some clever compiler-compiler tricks[1], it would become slightly
easier to write; you could remove one line from the part of the
type-checker that looks something like
if (isPointer(lhs_type) && isInteger(rhs_type)) yield(PTR);
else if (isInteger(lhs_type) && isPointer(rhs_type)) yield(PTR);
else if (isInteger(lhs_type) && isInteger(rhs_type)) yield(INT);
else fail();
However, I will point out that I'm taking a university course on
compiler design right now, and we're translating a language that has
pointers and integers and allows a limited form pointer arithmetic.
In "L3", you can write the equivalent of
q = p+i; q = p-i;
but you cannot write the equivalent of
i = p-q; q = i+p;
and I find it quite annoying. So IMNSHO, the commutativity of addition
is a very important feature of any programming language, regardless of
whatever trouble it may cause for the implementor.
Interesting side note: I'm reading the Metafontbook right now, and
IIRC, when Knuth wrote Metafont, he explicitly coded in a "canonical
order" for additions such that real-number addition in Metafont is always
perfectly commutative and associative, no matter the magnitudes of the
operands. I think that's a nice idea.
-Arthur
[1] - I could imagine a very-high-level compiler generator that would
let the implementor specify things like
commutative left-associative operator + does (blah blah blah)
left-associative operator - does (blah blah blah)
commutative left-associative operator * does (blah blah blah)
[...]
and it might be more of a pain in such a language to specify what happens
when you're dealing with non-commutative operators. Unfortunately, I
don't know of any such compiler generator language in the real world.