Skip to content
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

Issue with "Operator precedence": arrow function operator precedence #12914

Closed
dy opened this issue Feb 11, 2022 · 11 comments · Fixed by #18283
Closed

Issue with "Operator precedence": arrow function operator precedence #12914

dy opened this issue Feb 11, 2022 · 11 comments · Fixed by #18283
Labels
Content:JS JavaScript docs effort: small This task is a small effort. help wanted If you know something about this topic, we would love your help!

Comments

@dy
Copy link

dy commented Feb 11, 2022

MDN URL: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

What information was incorrect, unhelpful, or incomplete?

Maybe worth adding => operator precedence? It seems to be 2 - assignment group. TC39 members often use that precedence as argument.

MDN Content page report details
@github-actions github-actions bot added the needs triage Triage needed by staff and/or partners. Automatically applied when an issue is opened. label Feb 11, 2022
@sideshowbarker sideshowbarker added Content:JS JavaScript docs help wanted If you know something about this topic, we would love your help! effort: small This task is a small effort. and removed needs triage Triage needed by staff and/or partners. Automatically applied when an issue is opened. labels Feb 11, 2022
@hamishwillee
Copy link
Collaborator

Not sure. There is this note in the docs
image

But then in various proposals you see things indicating that yes, it is in group "2".

@wbamberg Thoughts?

@dy
Copy link
Author

dy commented Feb 14, 2022

In this case according to standard ?: ternary is also not operator but conditional assignment...

@hamishwillee
Copy link
Collaborator

Possibly. I'm deferring to the experts - @sideshowbarker , @wbamberg do you have an opinion. I'd be happy to add this myself.

@sideshowbarker
Copy link
Collaborator

sideshowbarker commented Feb 15, 2022

Maybe worth adding => operator precedence? It seems to be 2 - assignment group. TC39 members often use that precedence as argument.

Not sure. There is this note in the docs
image

Yeah, => is not an operator, so it doesn’t belong in the Operator Precedence table. Similar to how spread syntax is not an operator.

In this case according to standard ?: ternary is also not operator but conditional assignment...

In general, anything existing currently in that table that’s not an operator should be removed from the table — and certainly shouldn’t be used as a precedent for adding any other no-operators to the table.

@dy
Copy link
Author

dy commented Feb 15, 2022

I'm concerned that removing operators from the table makes it less useful. Standard is needed for implementors, but what comes to users - it's very helpful to learn when parens are needed in case of => or ?: (which is conventionally called operator, regardless of particular name in spec). Afterall they account for precedence (unlike statements), eg. it's important to know that () => a, b means (() => a), b and not () => (a, b), because => has higher precedence than ,

@hamishwillee
Copy link
Collaborator

@sideshowbarker I think @dy makes a valid point - if you're a user you want to know the precedence of particular "thingies" (a technical term we use in Australia) whether or not the thingies are technically operators.
I personally did not know they were not operators and would search here. There is nowhere else it would occur to me to search.
That said, it is important MDN does not incorrectly refer to something as an operator that is not - we're supposed to be adding clarity :-).

So we can remove them but we need to provide some excellent and obvious linking to where the information is provided.
OR we can keep them in the table, but make it very clear that some subset are not actually operators.

Thoughts?

@Josh-Cena
Copy link
Member

For the purpose of a reference page, I'm also pro-including it. Maybe the page title doesn't accurately reflect its content in this case, but it would still be useful to know how tightly a particular construct—even ...—binds to expressions/identifiers. Cross-referencing #12916 (comment):

The operators at this level don't really have more or less "precedence" than one another; they interact under special rules. See the following examples.

We should either include =>, or exclude =/./etc. (but mention them in an extension section), as IMO they operate with very similar mechanism: they don't allow arbitrary expressions as both operands, but are part of special syntaxes.

@sideshowbarker
Copy link
Collaborator

For the purpose of a reference page, I'm also pro-including it. Maybe the page title doesn't accurately reflect its content in this case, but it would still be useful to know how tightly a particular construct—even ...—binds to expressions/identifiers.

We could re-title (and redirect) the page. I guess we should.

But then that presents the different problem of what title to give to that page. Back when I was thinking about this, I think one thing that came to mind was that some of the things people wanted to include in the table had to do with the language’s rules for order of evaluation — rather than operator precedence.

So I dunno, maybe we could title the page “Operator precedence and order of evaluation” — which is somewhat ambiguous because it can be misread as being about operator order of evaluation, rather than “operator precedence” and “order of evaluation” being separate things (and I hope we have agreement that in general in languages they are two separate things…). But anyway, I don’t have a suggestion for how to make it both unambiguous and reasonably short.

@Josh-Cena
Copy link
Member

Josh-Cena commented Jul 7, 2022

I dunno either, to be honest... Originally I thought we should remove "assignment" as well since those don't really have the idea of "precedence" (they can't associate arbitrary expressions on LHS and RHS). But if we keep removing operators (/ constructs) we just make the page less useful without any gain of utility. Maybe we can make an additional section about how the non-operator constructs compare in binding tightness with those that are operators.

@js-choi
Copy link
Contributor

js-choi commented Jul 7, 2022

I mentioned this last year in #5365, and I’ve meant to open a pull request about this for a long time. (I think we’ve talked about it sometimes on the TC39 Matrix. I’ll try to find logs when I can.)

Anyways, my opinion remains the same:

=> is an operator in every way that = is an operator. If you consider = to be an operator, then I can think of no* good reason why => is not also an operator:

  • Both = and => take one “ordinary” RHS expression and one “binding” LHS (which is not an ordinary expression).
  • Both = and => form expressions that evaluate into values.

Compare [a] + f(), [a] = f(), and ([a]) => f(). In the = and => cases, only their RHSes (and not their LHSes) are expression operands. (We could quibble whether the LHS bindings should also count as “operands”, but it’s undeniable that they are not operands in the same way that +’s LHS is an operand.)

I think it’s completely appropriate to include => in any “table of operators” for JavaScript if it also contains =. I wouldn’t be against renaming it per se to make it more descriptive, but adding => to the table should not affect the decision to rename it that much.

(As an aside, one might say that it’s a misnomer to call = (also =>) a “binary” operator, since only its RHS is an ordinary expression. It’s more like a unary prefix operator with a funny extra LHS. In [a] = b + c, the b + c is an expression, but the [a] is not an expression. Though this is complicated by the fact that the LHS can contain default expressions like in [a = f()] = b + c, in which case the f() is an expression too…)

* Of course, there is one important difference: unlike =, => accepts either expressions or blocks as its RHS. So maybe ([a]) => f() is an operation on f(), but what about ([a]) => {}? I’m less certain about this. I feel like the {} block ought to be considered the “operand” of =>. There are plenty of operators with special rules, and operands don’t have to be restricted to ordinary expressions. The crucial part is that => definitely is still creating an expression, so if not an operator it is operator-like. This is still very different from, say, the spread syntax ..., which does not create an expression.


[Edit: Pasting here a response to a point from @sideshowbarker on Matrix that we could exclude both = and =>]

It would certainly would be consistent to exclude both = and => from being operators. But 
I don’t know if there’s any rigorous-but-still-useful definition of “operator” that would exclude =.

I think that you could rigorously define a JavaScript operator as a “syntactic token(s) that create an expression but which is not an atomic literal”, where an “expression” is a “syntax phrase that evaluates into a value at runtime”.


So 33 is not an operator. But yield is a nullary-or-prefix operator (with side effects). + is a prefix-or-binary operator. import() is a circumfix operator. And = and =>, I think, can reasonably be rigorously called operators, too. They’re certainly not atomic literals or statements.

In contrast, the ... spread syntax of array/object literals, the inner = in [x = 0] = y, and the match proposal’s ${ } interpolation syntax would not be operators, because they themselves do not create expressions.

(See also prior TC39 discussion sparked by the ${} syntax of match: 2021-12-08, 2021-12-08)

@Josh-Cena
Copy link
Member

I agree with the point here. At some point when I was trying to rephrase that page, I was tempted to define operators as "joiner of arbitrary expressions", in which case neither => and = are operators, because their LHS are bindings, not any expressions. But then the definition loses its point. I also did a poll in the TypeScript Discord server, and funnily got a unanimous result that = is an operator but => is not... In any case, I think in the case of a => a + 1, I would definitely say the "precedence" of => would be useful to the reader.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Content:JS JavaScript docs effort: small This task is a small effort. help wanted If you know something about this topic, we would love your help!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants