00:04
<bakkot>
jschoi: btw you can link to specific lines by clicking on the timestamp (and optionally shift-clicking on another timestamp to link to a range)
02:54
<ljharb>
@sideshowbarker: Yeah, I can certainly sympathize with the desire for rigor on MDN. And it certainly would be consistent to exclude both = and => from being operators.
I don’t know if there’s any rigorous-but-still-useful definition of “operator” that would exclude =, though. I think that you could rigorously define a JavaScript operator as a “syntactic token(s) that create an expression but which is not a literal”, where an “expression” is a “syntax phrase that evaluates into a value at runtime”.
So yield is a nullary-or-prefix operator (with side effects). + is a prefix-or-binary operator. import() probably should be called a circumflex operator (I forgot if it’s in the MDN table). And = and =>, I think, can reasonably be rigorously called operators, too. They’re certainly not literals or statements, heh.
i'm confused; => like in an arrow function? how is that an operator? what's the LHS operand in (a, b) => {}?
05:16
<jschoi>

Well, I’m arguing that => (at least when its RHS is an expression) is quite analogous to = in syntax. But you’re right in that =>’s analogy to = if the RHS is a block instead of an expression. And of course evaluation is deferred and not.

If “operator” means “syntactic construct that creates an expression that evaluates to a value, unless it is a literal”, then => definitely fulfills the former criterion. (I suppose one could argue that it may be considered a “literal” for functions…Now I’m wondering if there’s any useful distinction between compound literals and operators. Should [] be considered an operator?)

There’s also the fact that the evaluation of =>’s RHS is deferred. I think that’s a reasonable argument against => as operator, despite its creating an expression…In other words, one might reasonably argue that an operator must combine subexpressions that are first evaluated in LTR order. (But then why are nullary operators like yield, which do not involve any subexpressions, not disqualified? Or what about operators with special evaluation rules like short-circuiting operators?)

Anyways, I personally like the simplicity of “if it creates an expression, and it’s not a string/number/boolean literal, then it’s probably an operator”. And I personally would slot => in there.

But I now realize I’ve overstated my case with regards to the = analogy, since => can also have a block RHS. It’s a good point—I don’t think it necessarily disqualifies => from being an operator (i.e., the RHS of x => {} is a block, and that’s okay, because the whole thing is an expression). But I do accept that it certainly weakens my position, heh.

05:24
<ljharb>
(a, b) is an argument list, which isn't a thing. how can you operate on it?
05:27
<jschoi>
Well, the a in a = expr isn’t an expression either, right? You could say that = is operating on expr but not a per se, since a is not an expression. That’s the strongest part of the analogy, I think: compare ([a, b]) => f() and [a, b] = f(). In both cases, the LHS is not actually an expression.
05:28
<jschoi>
= “operates” on its RHS expression and not so much its LHS binding, and I suppose I would also say that => “operates” on its RHS expression and not so much its LHS arguments. In [x] = f(), = “operates” on f(), and, in ([x]) => f(), => “operates” on f(). 
But I do feel less sure about when the RHS is a block. I guess that I would say that, in ([x]) => {}, => “operates” on the empty block. But…yeah. (Either way, I don’t want to claim either that my personal mental model is the One True Way, of course, but at least it’s “simple” and “consistent”. 😅)
06:00
<sideshowbarker>
I guess there’s something different about JavaScript that makes the line between operators and non-operator things less clear? I mean in the case of C++ at least, I feel like the set of things that are actually operators is quite clear and I think I understand it pretty well — because it’s at least one part of the language that’s difficult for anybody to understand. But I could just be ignorant about some corner cases of C++ that I’m not familiar with
06:04
<sideshowbarker>
compare https://en.cppreference.com/w/cpp/language/operator_precedence
06:08
<sideshowbarker>
…and similarly, https://docs.python.org/3/reference/expressions.html#operator-precedence and https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html#nutsandbolts-precedence
06:12
<Jack Works>
I never figured out the subtle operator precedence. I use prettier and it will auto add ( ) for me to point out the precedence 😂
06:13
<Jack Works>
And it's also very confusing when I click Expression, I'm navigated to here
06:18
<jschoi>

Another can of worms is whether “compound literals” like array [ ] should be considered to be circumfix operators. Note that the Python chart does list them as “operators”. I don’t know if they really have thought of this as robustly as we are here; they may have just listed what felt right for them too.

Semantics are hard, and words are squishy. Maybe we should just use wordier phrases: “expression syntaxes”, “statement syntaxes”, etc. This is mostly a joke.

06:20
<sideshowbarker>
ah now that I think about it I can imagine that maybe the Python docs maintainers may also get issue reports about some cases similar to the ones we’ve gotten at MDN
06:21
<jschoi>
(I also note that they list lambda as an operator. But so are if/else—that’s what you get with a more expression-oriented language…)
06:21
<sideshowbarker>
oh
06:21
<sideshowbarker>
hmm yeah, point taken there