From: jlg@cochiti.lanl.gov (J. Giles)
Subject: Re: adding new operators on the fly
Organization: Los Alamos National Laboratory
Date: Thu, 19 Nov 1992 19:02:07 GMT

In article <MOSS.92Nov19094411@CRAFTY.cs.cmu.edu>, moss@cs.cmu.edu (Eliot Moss) writes:
|> I contend that when adding new operators it is much too confusing to allow the
|> user to choose/define precedence (at least), thoough associativity and
|> commutativity are less of a problem. The point is that it gets too complicated
|> for someone trying the READ the program and understand it. Rather, it is
|> likely better to take the approach of APL and Smalltalk: define one simple
|> evaluation order and otherwise require parenthesization.  [...]

This is why I hedged about precedence in my last article.  I disagree that
there should be no precedence (as in SmallTalk or APL).  On the other hand,
I also see very little value in allowing user-defined operators to be given
arbitrary precedence relationships.  I will give my actual opinion now:

The precedence of the following operators should be in this order:

      `^'     --  the exponentiation operator has highest precedence
      `*' `/' --  the multiply and divide on numeric types
      `+' `-' --  the add and subtract as well as unary minus and plus
      `<' `<=` `==' `~=' `>=' `>'  -- relionals
      `~'     --  boolean/bitwise NOT
      `/\'    --  boolean/bitwise AND
      `\/' `><' --  boolean/bitwise OR and XOR

All but the boolean operators should be defined for operands of any 
numeric types - including mixed-mode (putting aside, for the moment, 
the branch cut problems involved with complex exponents).  The boolean 
operators are bitwise if the operands are integer types, and are boolean
if the operands are boolean.

Now, character string operators for comparison have the same precedence
as the numeric comparisons.  The only other string operator is concatenation
which is the highest precedence string operator (and has *no* precedence
relative to the numeric operators since they can't be used together anyway).

User defined numeric types may have the usual operators overloaded to
support them.  These overloaded operators will retain the same precedence
they have for the intrinsic numeric operators.  This rule is simple: the
precedence of the above operator strings is always the same regardless
of how they are overloaded in terms of meaning.

Function referece syntax, array indexing, structure selection, and the
like are *not* operators and the syntax for them is independent of any 
precedence relationships for expressions.

Finally, new operators (and other intrinsics I've not mentioned) have
no *natural* precedence that I can discern.  And it would indeed lead
to very confusing code (at least from *some* users) to allow them to
define precedence for their new operators.  I'm personally biased in
favor of making all user defined infix operators have the same precedence
which is lower than the precedence of any intrinsic operator and to 
have all user defined prefix and postfix operators (all unary operators 
that is) have the same precedence which is higher than that of any 
intrinsic operator.

On the other hand, I could be convinced that the precedence should
default to what I said in the last paragraph, but that the user should
be allowed to change anything he likes - and if the code becomes 
unreadable that's the user's problem.

If you completely eliminate precedence, you might as well just give
up operators and user Forth or Lisp - since your expressions will
resemble those languages whether you like it or not.  On the other
hand, a great many operators with a great man precedence levels
is also a burden.  The best compromise is to pick a few obvious
operators, set their precedences carefully, and leave the rest
to the user.

-- 
J. Giles