Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the precedence of exponentiation lower than that of unary plus minus?

Most languages such as Fortran, Python, Ruby, Perl, Awk,... define precedence of the exponentiation operator higher than that of the unary plus and minus. This creates the following results:

In [1]: -2**1
Out[1]: -2

In [2]: -2**2
Out[1]: -4

Shells suchs as Ksh, bash, zsh have the precedence of those two operators reversed. This leads to the surprising result:

$ echo $((-2**1))
-2
$ echo $((-2**2))
4

Question: Why do shells have this particular precedence order? I assume this is genealogical based ksh > bash > zsh. But still ..

Note: exponentiation is not part of POSIX

Note: other languages/interpreters exist with a similar precedence order such as bc, tcl


Related questions:

  • Why does Ruby `**` operator have higher precedence than unary `-`?
like image 696
kvantour Avatar asked Jun 25 '20 10:06

kvantour


Video Answer


1 Answers

According to Wikipedia, the mathematical convention is that unary minus has a lower precedence than exponentiation. Some programming languages follow this, others don't.

But the above article also gives examples of different conventions for mathematical notation used in scientific publications1; e.g. the precedence of different ways of writing multiplication and division.


You asked: Why?

Well, in most cases there isn't a clear rationale for why particular language designers made particular choices; see the answers to this Q&A. However, we certainly can't justify the position that any particular precedence system is "correct" from a theoretical stand-point.

In general, the guiding principles for PL precedence systems seem to be:

  • Try to be consistent with the ancestors for this language.
  • Try to be consistent with perceived mathematical convention.
  • Do what "feels right" at the time.

The results are not consistent.

Fortunately:

  1. people tend to get used to the quirks of the languages that they use most of the time, and

  2. the exponentiation operator is not used very often2, and even less often with unary minus.

So it doesn't usually matter. (Except when someone gets it wrong in a context that has huge impact / consequences. And even then, there should be processes in place to deal with human error.)


The operator precedence for expression evaluation in bash is documented as being based on C operator precedence. (See man bash.) C doesn't have an exponentiation operator, but it does make unary + and - higher precedence than multiplication and division.

So in order to be consistent with C, the bash implementors needed to put the operator precedence of ** above *, / and % and below unary -. (Putting ** above unary - goes against the clear intent of C ... which is that unary - is above all other arithmetic operators.)


If your real question is not "why did they do it" but "are the reasons documented", you will probably need to trawl through developer mailing lists, source code repositories and so on for clues. Or maybe try asking the designers ... though they may not remember the reasons accurately.


1 - If mathematicians can't be consistent about notation, why is it a big deal that programming language designers aren't either?

2 - Indeed, many programming languages don't even support an exponentiation operator.

like image 50
Stephen C Avatar answered Oct 21 '22 10:10

Stephen C