On Nov 25, 2009, at 11:16 AM, Raoul Duke wrote:

## Advertising

hi, i'll ask what you think about the old saw that at least do no harm by being internally consistent if possible because well, wait, but then if "everything is an object" you end up with smalltalk's non-math precedence.

Now _that_ is a red herring. Smalltalk's *syntax* is separable from its *semantics*. Smalltalk's "one precedence level for all things that look like binary operators" is due to the fact that it has a large and *open* set of such "operators". Given the existence of points constructed by x...@y and the fact that you can add a number to a point, both 1@(2+3) and (1...@2)+3 make sense, so what should 1...@2+3 mean? What should the precedence of *+ or %% or &/ be? For exactly the same reason, APL, which originally had nothing resembling an object at all (it was 'everything is an array') had no operator precedence. In Eiffel, on the other hand, "to be the value of a variable is to be an object". There's no radical distinction between the Eiffel types INTEGER and STRING. It's an "everything is an object" language, yet it has fairly conventional operator precedence. The set of operators is extensible, with binary operators not in the standard having the tightest precedence, so that you get no precedence help with x*+y&/z. Haskell operators can have different precedence in different modules. Pascal managed to have "non-math precedence" without being internally consistent about anything much.

which is best? is this a subjective thing, as in each user will have a different preference? some will like smalltalk's approach, some won't, and that's ok?

You can't answer "what's BEST" without clarifying "best for what". For example, there is or was a dialect of Eiffel where if a non-predefined operator began with a predefined operator, it had the same precedence, so that <* would have the precedence of < and *> the precedence of *. Too bad if these were supposed to match in some way. I haven't yet seen any completely satisfactory solution to the problem of large operator sets, let alone extensible ones. The approach taken by APL and Smalltalk has the merit of being easy to remember (there is no precedence) and to use (never put two operators together without parentheses), at the price of familiarity for those operators that *are* familiar. For what it's worth, at school I was taught to use × for multiplication and ÷ for division, and to read 1/6 as one-and-sixpence. At University they taught me to read * as convolution. Especially / for division _still_ looks wrong, and % for remainder is downright weird. For a *small* fixed set of operators selected from exponentiation multiplication and division addition and subtraction comparison and or operator precedence (as originally developed for Fortran) makes a lot of sense; while the symbols might not match what I learned in school, the order does. My intuition from mathematics is that string concatenation belongs with the multiplication group. In some ways the Ada approach is interesting. There is no precedence defined between 'and' and 'or'. "p and q or r" is defined to be a syntax error that must be reported. In fact GCC tries to encourage people to write C as if that were true of C as well.