On Nov 25, 2009, at 11:16 AM, Raoul Duke wrote:
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
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
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
multiplication and division
addition and subtraction
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
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.