swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.57k stars 10.36k forks source link

[SR-552] Precedence of unary minus #43169

Open swift-ci opened 8 years ago

swift-ci commented 8 years ago
Previous ID SR-552
Radar None
Original Reporter drjdn (JIRA User)
Type Bug

Attachment: Download

Environment Ubuntu 15.10 on an x86-64 machine.
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | | |Labels | Bug, LanguageFeatureRequest | |Assignee | None | |Priority | Medium | md5: a269b223ebae08d734c7c3b8a3624fb1

Issue Description:

I'm not sure this will be considered a bug given the default precedence of prefix operators but the following code is inconsistent:

```swift
import CoreFoundation

infix operator ** { associativity right precedence 200 }

func ** (base: Double, power: Double) -> Double {
return pow(base, power)
}

print(-3*2*2)
print(0-3*2*2)
```
i.e. when interpreted as a binary operator swift returns the correct value but not when it is unary minus. Shouldn't prefix operators, namely unary minus, have precedence?

Best regards,
Jason

belkadan commented 8 years ago

I get "81.0, -81.0", which seems perfectly valid to me. It's not consistent with mathematical superscript notation for exponentiation, but if you really think of ** as a binary operator then it makes sense. -3 ** 2 ** 2

swift-ci commented 8 years ago

Comment by Jason D. Nielsen (JIRA)

I don't think my example is showing clearly what I mean. In math:

-3^2 = -(3*3) and not (-3) * (-3)

as exponentiation has higher precedence than subtraction. Swift has defined prefix operators to have highest precedence so treats
0-3^2 as (0 - (3*3)) differently that it does -3^2 as (-3) * (-3) which are mathematically equivalent. The whole point of allowing for programically overloaded operators is to make mathematical equations simplier to read (of course strictly my opinion). You provide associativity and precedence for binary operators which is great. My point I guess is that perhaps adding precedence to prefix operators would be a good idea else it would not be possible to have operators for mathematical structures that have the correct mathematical precedence without using a bunch of parens in many cases.

Best regard,
Jason

belkadan commented 8 years ago

I understood what you meant: "-3²" (to use Unicode) is definitely -9, not 9. I would guess that's at least partly because the alternative parse isn't very useful.

Again, when I read -3 ** 2, with the spaces present, I definitely parse that as "(-3)²". And we definitely do not want to make -3**2 do something different from -3 ** 2. So while this diverges, somewhat, from mathematical precedent, it's more consistent for the language.

Leaving my opinion aside for a moment, allowing prefix and infix (and postfix?) operators to mix precedence would be considered a language change, and as such would need to go through the Swift evolution process.

swift-ci commented 8 years ago

Comment by Jason D. Nielsen (JIRA)

In math there is no question that -3² = -9 as exponentiation has higher precedence than subtraction. Also 0-3² = 3² using the mathematical definition of =. It's math, can't really argue too much as you would be wrong ;). To me incorrectly evaluating numerical expressions by the rules of mathematics is a bug... just my own opinion. I'll look into making a language evolution request.

Best regards,
Jason

Dante-Broggi commented 6 years ago

I think this can be resolved as "Won't Do".

buzurgmekhr commented 1 year ago

cool 😎