[net.lang] Operator Precedence

bob@pedsgd.UUCP (Robert A. Weiler) (09/05/85)

References:

Organization : Perkin-Elmer DSG, Tinton Falls NJ
Keywords: 

I have a question. How did we end up with operator precedence in the
first place? This seems to cause many more problems than what would
seem to me to be obvious for algebraic expression - evaluate left
to right in the absence of parenthesis. It seems to me that most
programmers fully parenthesize anyway to avoid being bitten.
Can anybody make a compelling case for not doing it this way?

Bob Weiler.

ark@alice.UucP (Andrew Koenig) (09/06/85)

> I have a question. How did we end up with operator precedence in the
> first place? This seems to cause many more problems than what would
> seem to me to be obvious for algebraic expression - evaluate left
> to right in the absence of parenthesis. It seems to me that most
> programmers fully parenthesize anyway to avoid being bitten.
> Can anybody make a compelling case for not doing it this way?

OK, let's evaluate A=B+C strictly left to right.  First we copy B
into A, then we add C to A.  Now what do we do with the result?
Throw it away, I suppose.

I'm not being completely flip: that is exactly what C does if I
parenthesize the above expression so as to evaluate it strictly
left to right:    (A=B)+C

What to do?  Three solutions come to mind:

	1. Treat = specially.  This re-opens the precedence issue.

	2. Make assignment store into its RIGHT operand, as at
	   least one language (Neliac) has done.  Thus if we want
	   to set A to the sum of B and C, we write  B+C=A

	3. Make all operators group right to left, as APL has done.

chris@umcp-cs.UUCP (Chris Torek) (09/06/85)

There *are* languages without any operator precedence stuff (except
parentheses).  APL, Lisp, and FORTH spring to mind.  (The last two
may not count as one doesn't write typical algebraic expressions.)

Another interesting(?) idea would be to base operator binding on
spacing:  expressions that "look" like they are done first, are
done first.  (This isn't my idea, by the way.)  That is,

	a <- b+c * 4

would be equivalent to

	a <- (b + c) * 4

(Personally I think this is worse than no precedence).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

barmar@mit-eddie.UUCP (Barry Margolin) (09/08/85)

In article <262@pedsgd.UUCP> bob@pedsgd.UUCP (Robert A. Weiler) writes:
>

Well, we have Fortran to thank for operator precedence in programming
languages, I suspect.  As for how it got there in the first place, here
is my hypothesis.  It is an attempt to emulate the precedence inherent
in mathematical notation.  In mathematics, one does not normally write
the multiplication operator, one writes A*B as AB.  So, when one sees
the expression A+BC in mathematics, it is implicitly parsed as A+(BC).
A similar argument accounts for the higher precedence of exponentiation
(** or ^ in most Fortran-descendents):  N is generally interpreted as
                                      AB
   N
A(B ).  As for the higher precedence of division, that may be because of
                                    N
fractions being written as N/D when - is not convenient, or it might be
                                    D
because division is to subtraction as multiplication is to addition, so
the corresponding operations have similar precedence.  Also, division is
almost associative with multiplication, i.e. A*B/C can be interpreted as
(A*B)/C or A*(B/C) without affecting the mathematical answer (although
the computer answers might be different, due to the problems of computer
representations of numbers).

The "founding fathers" of high-level languages probably didn't
anticipate the confusion that would ensue when their simple rule of
operator precedence (* and / higher than + and - [= was not considered
part of an expression, it was part of the syntax of an assignment
statement, and the original Fortran didn't even have comparison
operators (remember arithmetical IF?)]) got extended to handle a dozens
of operators.  Even after comparison operators came around, their
results could usually be used only in boolean expresions, and A+(B==C)
is not valid in many languages, so it was very natural that A+B==C
should be forced to mean (A+B)==C.

The only operator precedence I can ever remember is that ^ is higher
than * and /, which are higher than + and -, and that comparison
operators are the lowest.  And, in the case of languages in which
assignments are expressions (are there any other commonly-used ones
besides C [not counting functional languages, in which everything is an
expression by definition]?), assignments are usually even lower.  These
last two are easy to remember because they match the common use: one
usually uses comparisons and assignments at the highest possible levels,
rather than using them as subexpresions; the C expression
		a*b==c+d
almost always is intended to compare the two outer expressions, rather
than to involve the result of the inner comparison in the arithmetic
expression.
-- 
    Barry Margolin
    ARPA: barmar@MIT-Multics
    UUCP: ..!genrad!mit-eddie!barmar

debray@sbcs.UUCP (Saumya Debray) (09/11/85)

As an aside, it's interesting to note that operator precedence parsers
permit one to extend the syntax of the language through "user-defined
operators".  This is the case with Prolog, for example: you declare an
operator with its relative precedence and type (prefix/postfix/infix), and
then you can use this operator in the program.
-- 
Saumya Debray
SUNY at Stony Brook

	uucp: {allegra, hocsd, philabs, ogcvax} !sbcs!debray
	arpa: debray%suny-sb.csnet@csnet-relay.arpa
	CSNet: debray@sbcs.csnet

peter@graffiti.UUCP (Peter da Silva) (09/17/85)

> Another interesting(?) idea would be to base operator binding on
> spacing:  expressions that "look" like they are done first, are
> done first.  (This isn't my idea, by the way.)  That is,
> 
> 	a <- b+c * 4
> 
> would be equivalent to
> 
> 	a <- (b + c) * 4
> 
> (Personally I think this is worse than no precedence).

I'd hate to program in that, but that's certainly an interesting idea. Then
you could indicate compound and continued statements by indentation:

	if a < b
	  blah
	  blah
	else
	  while not finished
	    do this,
	      and that
	      and the other thing
	    remember to reinit the loop!
	and in any case...

Any programming languages actually do this, by the way?

rcd@opus.UUCP (Dick Dunn) (09/18/85)

> I have a question. How did we end up with operator precedence in the
> first place? This seems to cause many more problems than what would
> seem to me to be obvious for algebraic expression - evaluate left
> to right in the absence of parenthesis...

Ahh, yes...the precedence battles.  Contrary to popular belief, precedence
in programming languages is not so much a matter of mathematical practice
as of programming language practice.

Consider that in the presentation of mathematics, the multiplication
operator is normally elided.  The precedence of multiplication in
mathematical usage is more an artifact of the physical "closeness" of the
factors than of any innate property of multiplication.

Next consider division.  If there is any question of the grouping of the
elements of the divisor or dividend, we use a long fraction bar.  Again,
the typographic presentation of the operation conveys more information than
any assumed precedence.

We give addition and subtraction equal precedence because they're "what's
left over" after dealing with multiplication and division by layout rules,
and we give them left associativity because our language works left-to-
right.

Mathematics does not have an "assignment" operator.  The = notation is used
to indicate definition or equality (as defined by context) and occurs only
once in a "statement".  There is a sense of precedence here.

Any more global notations (such as universal or existential quantifiers)
tend to be done with parenthesized notation to avoid ambiguity.

In fact, if you survey existing languages, it is rare to find a pair which
agree on the precedence and associativity of all of the operators they have in
common.  One of the more notable languages at variance with "the rest" is
SNOBOL, in which the precedence of * is higher than /.  If you play around
with it a little bit, you might be surprised at how often the SNOBOL
precedence of * over / gives a more natural notation for an expression.
-- 
Dick Dunn	{hao,ucbvax,allegra}!nbires!rcd		(303)444-5710 x3086
   ...Lately it occurs to me what a long, strange trip it's been.

pcf@drux3.UUCP (FryPC) (09/22/85)

>> Another interesting(?) idea would be to base operator binding on
>> spacing: 

> I'd hate to program in that, but that's certainly an interesting idea. Then
> you could indicate compound and continued statements by indentation:
> Any programming languages actually do this, by the way?

Yes, occam, the concurrent language developed by Inmos does just that. They
justify it on two grounds: firstly, most people make mistekes (sic) by 
forgetting braces rather than forgetting to indent; and secondly, most
terminals only have 24 lines and you shouldn't waste them. 

To mess with your example:
(Note that the 'if' performs the code after the first 'true' condition so
that it can also act as a 'switch' statement, and 'true' acts as an 'else'
statement.)

   if
      a < b
         blah;
         blah;
      a < c
	 on the other hand;
      true
         while \ finished
            this;
            and that;
            and the other thing;

      etc.;


Peter Fry
drux3!pcf

johnny@alibaba.UUCP (Lars Svensson) (09/23/85)

In article <205@graffiti.UUCP> peter@graffiti.UUCP (Peter da Silva) writes:
>I'd hate to program in that, but that's certainly an interesting idea. Then
>you could indicate compound and continued statements by indentation:
>
>	if a < b
>	  blah
>	  blah
>	else
>	  while not finished
>	    do this,
>	      and that
>	      and the other thing
>	    remember to reinit the loop!
>	and in any case...
>
>Any programming languages actually do this, by the way?

I think the British company Inmos uses this approach in occam,
a language tailored for their "transputer" micro.

	...{decvax, seismo}!mcvax!enea!alibaba!johnny
	(Lars Svensson, Dept. of Applied Electronics, Univ. of Lund, Sweden)

horst@leadsv.UUCP (John Selhorst) (09/23/85)

In article <205@graffiti.UUCP>, peter@graffiti.UUCP (Peter da Silva) writes:
> I'd hate to program in that, but that's certainly an interesting idea. Then
> you could indicate compound and continued statements by indentation:
> 
> 	if a < b
> 	  blah
> 	  blah
> 	else
> 	  while not finished
> 	    do this,
> 	      and that
> 	      and the other thing
> 	    remember to reinit the loop!
> 	and in any case...
> 
> Any programming languages actually do this, by the way?

Yes, take a look at Occam. It's been a while since I've looked at it, but
remember something very much like that. I don't find it very easy to read
but with a little adaptation it might be quite usable. A major advantage
is that all of the implementations I've heard of include a syntax-directed
text editor which makes writing like that much easier - you don't have to
space over on every line. Occam also has some other nifty stuff you might
want to check out. It was developed by Inmos and is used with their
Transputer.

(The above was probably written by someone else illicitly logged into my
 account. But send me mail anyway, as s/he will probably end up reading
 it anyway.)

John Selhorst
 {(ucbvax!dual!sun) (ihnp4!qubix)}!sunncal!leadsv!horst
 {{allegra ihnp4 dual}!fortune decvax!decwrl}!amdcad!cae780!leadsv!horst


-- 
 {(ucbvax!dual!sun) (ihnp4!qubix)}!sunncal!leadsv!horst
 {{allegra ihnp4 dual}!fortune decvax!decwrl}!amdcad!cae780!leadsv!horst

stephen@datacube.UUCP (09/25/85)

PROMAL, a compiled pseudo-PASCAL-C-PL/M language for the Commodore 64
does.