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

**posted on**

- David Frauzel

September 27, 2004, 5:27 am

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

> 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

>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

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

is unary minus.

4-2

is subtraction.

--

Bart.

>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

******4is unary minus.

4-2

******4is subtraction.

--

Bart.

## Re: Precedence of exponentiation

> 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

parsed as -(2

before doing exponentiation.

-Joe

> 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 isparsed 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

> 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

>

> 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

$5a62ac22@per-qv1-newsreader-01.iinet.net.au:

> 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

-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) ?

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

Xho

--

-------------------- http://NewsReader.Com/ --------------------

Usenet Newsgroup Service $9.95/Month 30GB

>

> 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

--

-------------------- http://NewsReader.Com/ --------------------

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

Perl cannot be parsed simply by looking at tokens.

My favorite example is this:

cat temp.pl

print time / 2 ; # / ; die "This die() is

print sort / 2 ; # / ; warn "This warn()

perl -l temp.pl

-Joe

> 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

:) > print sort / 2 ; # / ; warn "This warn()

:) > 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 ();'

:)

:) > 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 ();'

#### Site Timeline

- » FAQ 1.3 Which version of Perl should I use?
- — Next thread in » PERL Discussions

- » perl string match
- — Previous thread in » PERL Discussions

- » s suffix question
- — Newest thread in » PERL Discussions

- » need help creating a 404 file
- — The site's Newest Thread. Posted in » HTML Markup Language