-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bit shift operator precedence #13079
Comments
Reference table here: https://en.wikipedia.org/wiki/Order_of_operations#Programming_languages Bitwise shift left and right is level 5, above ("lower than", technically) + / -. |
Giving The linked study looks interesting but I didn't manage to extract a concrete recommendation at a glance. Do you have a strong take-away from it? |
None at all. I knew Ritchie never liked the precedence of bitwise operators in C; I wasn't suggesting that we emulate them. I was just providing a couple of reference points for the decision :) |
I wonder if we could do better with precedence in general by borrowing the idea from Fortress of making precedence a partial ordering and having it be an error not to parenthesize ambiguous cases. |
Wouldn't you still have to define a relative ordering of operators? I don't see how that proposal is that much better than having fixed rules with a couple ambiguous cases in terms of precedence level. |
I do feel while erroring or at least warning on potentially ambiguous statements would be nice. It seems though like something a linter could deal with instead. |
I prefer bit ops binding more tightly than arith ops, and, subordinately, unary ops binding more tightly than binary ops. |
Clarification:
|
Proposal: move bit shifts one notch higher than It's also possible shifts should be merged into the |
One issue: |
I concur: arith < shift < power There does not appear any explicit advantage to |
Done. |
deprecate parsing `*` inside `<<`. part of #13079
This seems important to document (and not just in NEWS). I'm not sure if Compat can handle this or is wanted there. |
The precedence has not actually been changed yet; I just required parentheses. Adding parens is easier than typing |
This is a pretty big change. While I can see that this actually does work substantially better for most arithmetic expressions where you want to use bitshifts, it is a different convention from what every other language uses and could break the principle of least surprise. It may especially surprise a lot of people coming from C++ where the bitshift operator is a notoriously common target for overloading because of its convenient place in the precedence table and the fact that the >> notation suggests chaining. Julia Libraries that overloaded >> to denote monadic bind or andthen semantics will be shafted by this change if it goes live. This is a common enough expression that it could cause quite a lot of code breaking. Then again, Go also decided to give >> higher precedence than + (it is a multiplicative operator), so there is at least one other language that made the same decision. Pascal also had a similar precedence, it's mainly a case of most languages after C copying C's operator precedence table. So there is a case for adopting this as the more logical precedence for bitshift. |
Julia libraries should absolutely not be doing this. Overloading random operators like |
The point about principle of least surprise is valid, however – it's concerning to have different precedence from other mainstream languages, evn if that precedence is a bit unfortunate. |
afaik the principle of least surprise was developed to encourage cognitive consonance rather than conform to alternative practice (translation: we have the opportunity to do it better, and we should -- it takes little effort to learn this specific distinction, and overcoming Julia promulgating a worse practice takes enormous effort) |
Scrutinizing the operator precedence table, it struck me as a bit odd that bit shift operators have their own precedence level, strictly lower than multiplication.
a*b>>c*d
is an ugly expression to be sure, but it's parsed as(a*b)>>(c*d)
, which doesn't make a whole lot of sense.Since
a<<b
meansa*2^b
,<<
should perhaps have the same precedence as*
, or maybe even the same precedence as^
. Or maybe it should be moved to one notch higher than*
, instead of one notch lower (putting it between*
and//
).The text was updated successfully, but these errors were encountered: