crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.34k stars 1.62k forks source link

Priority of unary `-` relative to `**` #12999

Open konovod opened 1 year ago

konovod commented 1 year ago

What aspect of the language would you like to see improved?

Change operator precedence, so ** will have higher priority then unary - (and perhaps over other unary operators).

What are the reasons?

In most languages I've checked (Ruby, Python, Julia, Octave, VB6) -2**2 gives -4 (operation ** have higher priority than unary -). This is IMHO consistent with mathematical notation (-22 = 4). Excel (and VBScript\Google Sheets) returns 4 though, so there is no universal consensus.

Include practical examples to illustrate your points.

More complete list of languages (compiled from here and my own checks):

Optionally add one (or more) proposals to improve the current situation.

In Crystal, -2**2 gives 4, this is documented, but i wonder if there is any motivation behind this decision or just coincidence. JavaScript approach looks appealing to me, but I'm not sure how it fits the rest of language. Of course, changing it at this stage would be a breaking change for minimal profit, but i haven't found corresponding issue, so I think there should be one. If consensus is to keep current behavior, maybe this worth noting in a Differences from Ruby.

asterite commented 1 year ago

This was already discussed in the past: https://github.com/crystal-lang/crystal/pull/9684

We made some changes back then so it's unlikely we'll make them again.

There's more discussion here: https://forum.crystal-lang.org/t/exponentiation-operator-has-unexpected-behaviour/2457

asterite commented 1 year ago

Or maybe it was a separate discussion. I think given that 1.0 is out this is unlikely to change.

BlobCodes commented 1 year ago

Or maybe it was a separate discussion. I think given that 1.0 is out this is unlikely to change.

AFAIK there were concerns about the parser complexity because number literals like -2 can't directly be converted to a token.


Until at least Crystal 2.0 (and probably even afterwards), this should stay as-is. Changing the operator precedence post-1.0 will introduce lots of subtle breaking changes, without any useful compiler messages.

oprypin commented 1 year ago

JavaScript's solution sounds great - always require parentheses. It is not subtle. To me it seems perfectly fitting for 2.0. And maybe even the parser can have a retroactive check in a way that doesn't harm the main path.

Screenshot

straight-shoota commented 1 year ago

A much more softer measure we can introduce without any hassel: The formatter could apply parenethesis for this. That would clearly express associativity in the code.

oprypin commented 1 year ago

Both is best 🙂 They complement each other

straight-shoota commented 1 year ago

I'd like to avoid having the compiler spit out excessive warnings. There's not much point in adding warnings for anything the formatter would reformat. So whether this should trigger a warning is debatable. The code is technically not ambiguous, the behaviour is clearly specified. So why should the compiler warn about anything? Having the formatter change the code to a representation that avoids any potential misunderstanding is much better than printing warnings.