# Precedence of exponentiation

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
Rhetorical question.

Why does Perl give such high precedence to the exponentiation operator,
"**"?

perlop makes it very clear that -2**4 is equivalent to -(2**4), not (-2)
**4. So -2**4 gives you -16, not 16. So Perl facilitates people who
prefer unary operators to have less significance than binary operators,
which seems to be completely counter to the general rules of algebra.

But that's not why I'm asking the question, actually. What bugs me is
this:

2**-4

.... gives you 2**(-4), not -(2**4). Looking at 2**-4, it seems obvious
that this should be the case, but it apparently defies the above stated
precedence rule. A token parser should recognize that the unary minus has
lower precedence than **, and push ** below the unary minus, in exactly
the same way it would with -2**4.

So, I'm left wondering if the Perl parser is actually going out of its
way to make sure that a unary minus on the right side of binary
exponentiation is given higher precedence than exponentiation, while on
the left side, it has lower precedence. Clearly, if that is indeed the
case, Perl is going out of its way to make sure that -2**4 arbitrarily
works one way, and 2**-4 works another. The double standard, coupled with
the illogical precedence to begin with, smells of some onerous backwards
compatibility that probably isn't even relevant any longer.

In building a token parser based on Perl, I am tempted to altogether
abandon this peculiar behavior, and give binary exponentiation the
precedence it seems to rightly deserve: lower than unary minus.

## Re: Precedence of exponentiation

David Frauzel wrote:

> Rhetorical question.
>
> Why does Perl give such high precedence to the exponentiation operator,
> "**"?

Because it attempts to follow after the way mathematicians write
algebraic expressions.

>
> perlop makes it very clear that -2**4 is equivalent to -(2**4), not (-2)
> **4. So -2**4 gives you -16, not 16. So Perl facilitates people who
> prefer unary operators to have less significance than binary operators,
--------------------------------------------------------^^^^^^^^^^^^^^^^

only the binary exponentiation operator -- multiplication, division,
addition and subtraction have lower precedence than unary - .

> which seems to be completely counter to the general rules of algebra.

According to perldoc perlop, yes, ** has higher precedence than unary -.
So yes, -2**4 should give -16, since the exponentiation is done first,
then the unary - on that result.  And I disagree with you regarding the
"general rules of algebra" -- if a=2 and b=4, then

b                                   -b
-a    in algebra would be -16 -- and a    would be 0.0625 .  For
clarity, though, most folks would probably parenthesize them both.

Also, in the case of computer languages, it may help to give such
examples using variables rather than constants, as in -\$a**\$b and
\$a**-\$b, to avoid the issue of whether -4 is a constant or an expression.

>
> But that's not why I'm asking the question, actually. What bugs me is
> this:
>
> 2**-4
>
> ... gives you 2**(-4), not -(2**4). Looking at 2**-4, it seems obvious
> that this should be the case, but it apparently defies the above stated
> precedence rule. A token parser should recognize that the unary minus has
> lower precedence than **, and push ** below the unary minus, in exactly
> the same way it would with -2**4.

In most other languages, 2**-4 would give a syntax error.  I think Perl
treats it as special (a DWIM), with the definition 2**(-4), because,
again, that would be the common thing in algebra.  It certainly seems
better than returning -16 for 2**-4, which doesn't seem good at all.
But perlop seems to leave that one undefined.  One can always use
parentheses to make the intent crystal clear.

Deparse shows \$a**-\$b deparsing as \$a**(-\$b).

>
> So, I'm left wondering if the Perl parser is actually going out of its
> way to make sure that a unary minus on the right side of binary
> exponentiation is given higher precedence than exponentiation, while on
> the left side, it has lower precedence. Clearly, if that is indeed the
> case, Perl is going out of its way to make sure that -2**4 arbitrarily
> works one way, and 2**-4 works another. The double standard, coupled with
> the illogical precedence to begin with, smells of some onerous backwards
> compatibility that probably isn't even relevant any longer.

I think Perl's got it right -- certainly what I think it should mean, if
it has to mean something other than a syntax error.  It would be good,
though, to have it documented in perlop.

>
> In building a token parser based on Perl, I am tempted to altogether
> abandon this peculiar behavior, and give binary exponentiation the
> precedence it seems to rightly deserve: lower than unary minus.

I reckon you can build your parser any way you want.

--
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl

## Re: Precedence of exponentiation

> Because it attempts to follow after the way mathematicians write
> algebraic expressions.

Point me to some reference material where it says so? I'm curious,
really. Because I've probably forgotten most of even my high school
algebra - the stuff that doesn't go along with programming, anyway - so
maybe I'm just completely misremembering the part where the teacher said
that unary minus behaves differently on the left and right side of
exponentiation. (And my Windows calc application seems to disagree, too.)

>> who prefer unary operators to have less significance than binary
>> operators,
> --------------------------------------------------------^^^^^^^^^^^^^^^
> ^

Type. Yes, I meant exponentiation operators. :p

>   So yes, -2**4 should give -16, since the exponentiation is done
>   first,
> then the unary - on that result.  And I disagree with you regarding
> the "general rules of algebra" -- if a=2 and b=4, then
>
>        b                                   -b
>      -a    in algebra would be -16 -- and a    would be 0.0625 .  For
> clarity, though, most folks would probably parenthesize them both.

You only have to paranthesize (-2)**4, since you don't want Perl's whacky
exponentiation precedence to get in the way of what you mean. In the case
of 2**-4, you don't, because Perl knows you mean something else. This is
why I used the word "arbitrary". And continue to wonder about what you're
calling "undefined" - whether it's for some backward-compatibility reason
that is no longer relevant to modern native Perl speakers.

> In most other languages, 2**-4 would give a syntax error.  I think
> Perl treats it as special (a DWIM), with the definition 2**(-4),
> because, again, that would be the common thing in algebra.  It
> certainly seems better than returning -16 for 2**-4, which doesn't
> seem good at all. But perlop seems to leave that one undefined.  One
> can always use parentheses to make the intent crystal clear.

The very point of precedence is so that you don't need to use parantheses
if you're feeling lazy. (Certainly that is so with how list operators
behave - having different precedence on the left and right sides.) We
could throw precedence out the window if you just put everything in
parantheses. Therefore, precedence should be designed with the human in
mind, and what *most* humans will want to "mean" when they do not use
parantheses.

Am I really in the minority in thinking that -2**4 should mean (-2)**4?

> I reckon you can build your parser any way you want.

I'd prefer, though, to know Larry Wall's reasoning - so that if there's
in fact some astoundingly good reason I am just not seeing, I can add the
extra code necessary in my parser to treat exponentiation specially.
(With regards to unary minus as the next lexeme.)

## Re: Precedence of exponentiation

[...]

> Am I really in the minority in thinking that -2**4 should mean (-2)**4?

Yes.  -2**4 is -(2**4) in all mathematical texts.

To convince yourself, look up a series with alternating sign, say
the series for sin(x) in any suitable book.  The sign will be written
(-1)**n, not -1**n.

Anno

## Re: Precedence of exponentiation

In our last episode, the evil Dr. Lacto had captured our hero,

>Am I really in the minority in thinking that -2**4 should mean (-2)**4?

Well.. considering (-2)**4 == 2**4 , I would say that the answer is "Yes,
most people would apply the unary-minus after the exponentiation."

I've got a high-school-math teacher in the house.  I'll see what she
thinks tonight.

hymie!          http://www.smart.net/~hymowitz hymie@lactose.smart.net
===============================================================================

## Re: Precedence of exponentiation

wrote:
> Am I really in the minority in thinking that -2**4 should mean (-2)**4?
>

What shold 4-2**4 mean?

Error or 4-(2**4) or (4-2)**4 or (4,16)

## Re: Precedence of exponentiation

José Luis Pérez Diez wrote:

>wrote:
>> Am I really in the minority in thinking that -2**4 should mean (-2)**4?
>>
>
>What shold 4-2**4 mean?

You are confusing the two types of minus sign uses: 1) as a unary sign,
2) as a replacement for "+" in addition, i.e. in subtraction

-2**4

is unary minus.

4-2**4

is subtraction.

--
Bart.

## Re: Precedence of exponentiation

wrote:
> You are confusing the two types of minus sign uses: 1) as a unary sign,
> 2) as a replacement for "+" in addition, i.e. in subtraction
>
I know it , 3 if you count also the unary operator, to use - as a sign
only the number has to be in string or in the exponent part of a real,
form "-0.03" or '-0.03' versus 0.03 or .3e-1 but '-.3e-1'.

I usually think of the unary operator as 0-(expression).

## Re: Precedence of exponentiation

David Frauzel wrote:

> But that's not why I'm asking the question, actually. What bugs me is
> this:
>
> 2**-4
>
> ... gives you 2**(-4), not -(2**4). Looking at 2**-4, it seems obvious
> that this should be the case, but it apparently defies the above stated
> precedence rule. A token parser should recognize that the unary minus has
> lower precedence than **, and push ** below the unary minus, in exactly
> the same way it would with -2**4.

It would be absurd to expect the minus sign to move like that.

The exponentation operator takes two arguments.  It's high precedence
means that the two arguments must be made available before doing
anything else (such as addition or multiplication).  -2**-4 is
parsed as -(2**(-4)) which gathers up the right-hand side of the **
before doing exponentiation.
-Joe

## Re: Precedence of exponentiation

> It would be absurd to expect the minus sign to move like that.
>
> The exponentation operator takes two arguments.  It's high precedence
> means that the two arguments must be made available before doing
> anything else (such as addition or multiplication).  -2**-4 is
> parsed as -(2**(-4)) which gathers up the right-hand side of the **
> before doing exponentiation.

Exactly. So (in the parser) its right side seems to regard ** with
different precedence than does its left. Right? Er, correct...?

I finally looked up perlguts again (to prove to myself I'm not just
imagining that Perl uses parse trees), and noticed the -Dx option. I
don't have DEBUGGING compiled in (ActivePerl), but -MO=Concise gave me
the following for print -\$foo**-\$bar:

1     <0> enter ->2
2     <;> nextstate(main 1 -:1) v ->3
3        <0> pushmark s ->4
8        <1> negate[t5] sK/1 ->9
7           <2> pow[t4] sK/2 ->8
-              <1> ex-rv2sv sK/1 ->5
4                 <#> gvsv s ->5
6              <1> negate[t3] sK/1 ->7
-                 <1> ex-rv2sv sK/1 ->6
5                    <#> gvsv s ->6

I'll play around with some of the other debugging tools mentioned to see
if I can actually "watch" the parse as it happens, so I can see exactly
when Perl decides that the second unary should be applied to the second
constant, whereas the first is applied to exponentiation.

## Re: Precedence of exponentiation

David Frauzel wrote:

> Exactly. So (in the parser) its right side seems to regard ** with
> different precedence than does its left. Right? Er, correct...?

It's not precedence.  It's grammer.  The way you've phrased the question
indicates that you may not fully understand how yacc and other
compiler compilers work.  There's more to parsing than just precedence.
-Joe

## Re: Precedence of exponentiation

David Frauzel wrote:

>
> perlop makes it very clear that -2**4 is equivalent to -(2**4), not (-2)
> **4. So -2**4 gives you -16, not 16.

I think this is so that something like '17 - 2 ** 4' evaluates to 1 ...
which is certainly what I would want it to evaluate to. Without that
precedence, wouldn't '17 - 2 ** 4' evaluate to 50625 (ie 15 ** 4) ?

When I see an expression like '17 - 2 ** 4' I think '17 - (2 ** 4)', not
'(17 -2) ** 4'. If you really want to raise  -2 to the 4th power write
it as (-2) ** 4.

That's the nice thing about precedence - if you don't like it the way it
is, it's very easy to override :-)

Similarly, I don't think I would ever want 2 ** -4 to evaluate to -16.

Cheers,
Rob

--
To reply by email u have to take out the u in kalinaubears.

## Re: Precedence of exponentiation

> I think this is so that something like '17 - 2 ** 4' evaluates to 1 ...
> which is certainly what I would want it to evaluate to. Without that
> precedence, wouldn't '17 - 2 ** 4' evaluate to 50625 (ie 15 ** 4) ?

That's the difference between unary minus and binary minus. The parser
picks up on the difference and correctly evaluates the above regardless of
the weird binary exponentiation operator. :}

> Similarly, I don't think I would ever want 2 ** -4 to evaluate to -16.

Yes, I'm sure no one would! :} But do you really want -2**4 to evaluate to
-16? ;}

## Re: Precedence of exponentiation

> Rhetorical question.
>
> Why does Perl give such high precedence to the exponentiation operator,
> "**"?

Because that is the way that the people who mostly use exponentiation
expect it to happen.

> perlop makes it very clear that -2**4 is equivalent to -(2**4), not (-2)
> **4. So -2**4 gives you -16, not 16. So Perl facilitates people who
> prefer unary operators to have less significance than binary operators,
> which seems to be completely counter to the general rules of algebra.

Where did you learn the general rules of algebra?  Exponentiation
binds tighter than negation.  I suspect that the main reason this decision
was made so that the negation would always be meaningful.  (If it bound
tighter than exponentiation, it would be trivial in the case of even
exponent, and often illegal in the case of most fractional exponents [until
you get to imaginary numbers]).  So we interpret in the way that makes it
more often meaningful.  But regardless of why it is interpreted that way,
that is the way it is interpreted.

> But that's not why I'm asking the question, actually. What bugs me is
> this:
>
> 2**-4
>
> ... gives you 2**(-4), not -(2**4).

Of course it does.  The alternative is just laughable.

> Looking at 2**-4, it seems obvious
> that this should be the case, but it apparently defies the above stated
> precedence rule. A token parser should recognize that the unary minus has
> lower precedence than **, and push ** below the unary minus, in exactly
> the same way it would with -2**4.

Don't be ridiculous.  The assymetry belongs to the negation, not the
exponentation.  The unary negation negates the term to its right.  Since
"2**" is not a term, and isn't to its right, it is not what it negates.

Xho

--
Usenet Newsgroup Service                        \$9.95/Month 30GB

## Re: Precedence of exponentiation

David Frauzel wrote:

> The double standard, coupled with
> the illogical precedence to begin with, smells of some onerous backwards
> compatibility that probably isn't even relevant any longer.
>
> In building a token parser based on Perl ...

Perl acts differently when it is expecting a term as opposed to when it
is expecting an expression, as in 2**-4.

Perl cannot be parsed simply by looking at tokens.
My favorite example is this:

cat temp.pl
print time / 2 ; # / ; die "This die() is *not* executed!!";
print sort / 2 ; # / ; warn "This warn() *is* executed.";
perl -l temp.pl

-Joe

## Re: Precedence of exponentiation

> Perl acts differently when it is expecting a term as opposed to when
> it is expecting an expression, as in 2**-4.

Yes. It seems to be a fairly simple matter to predict what's expected next,
so that such distinctions as the following can be made...

> Perl cannot be parsed simply by looking at tokens.
> My favorite example is this:
>
> cat temp.pl
>    print time / 2 ; # / ; die "This die() is *not* executed!!";
>    print sort / 2 ; # / ; warn "This warn() *is* executed.";
> perl -l temp.pl

The lexer catches that, though, not the parser. :) It's still all a matter
of tokens - but / / must be recognized as m// in the lexer. A recursive
character-based (state machine) lexical analyzer should be able to handle
such situations.

I think I finally grok'ed my problem, though. I was completely ignoring
that unary minus is right-associative. (Well, and I'm not sure that's all
of it, but I've isolated the bug in my parser and I'm testing a fix for
it.)

## Re: Precedence of exponentiation

David Frauzel (nemo@weathersong.net) wrote on MMMMXLVI September MCMXCIII
:)
:) > Perl cannot be parsed simply by looking at tokens.
:) > My favorite example is this:
:) >
:) > cat temp.pl
:) >    print time / 2 ; # / ; die "This die() is *not* executed!!";
:) >    print sort / 2 ; # / ; warn "This warn() *is* executed.";
:) > perl -l temp.pl
:)
:)  The lexer catches that, though, not the parser. :) It's still all a matter
:)  of tokens - but / / must be recognized as m// in the lexer. A recursive
:)  character-based (state machine) lexical analyzer should be able to handle
:)  such situations.

The lexer can only catch that if it gets feedback from the parser.
Without knowing what to expect, a lexer can't know whether a token
that starts with a / is a division, or a regex.

Abigail
--
perl -wle '\$, = " "; sub AUTOLOAD {(\$AUTOLOAD =~ /::(.*)/) [0];}
print+Just (), another (), Perl (), Hacker ();'