1

Why is the following a syntax error?

(()=>{console.log(1)}())

()=>{console.log(1)} is clearly(?) an expression that evaluates to a fat arrow function, and () "should" call it?

Presumably because it is ambiguous. What is the ambiguity?

Obviously, I realise the following works:

(()=>{console.log(1)})()
Ciaran Gallagher
  • 3,895
  • 9
  • 53
  • 97
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
  • Because your left () is empty. – SPlatten Feb 03 '20 at 15:56
  • 2
    @SPlatten no, this is not the issue. – Seblor Feb 03 '20 at 15:57
  • 3
    I really don't understand why people are downvoting this question. This is a legit question about JS parsing... – Seblor Feb 03 '20 at 15:58
  • `(()=>{})()` is a shorthand for `IIFE` https://developer.mozilla.org/en-US/docs/Glossary/IIFE – Denis Tsoi Feb 03 '20 at 16:01
  • @DenisTsoi OP's question is why does it need to be enclosed in parenthesis to be called ? – Seblor Feb 03 '20 at 16:02
  • @Seblor Possible reason for downvotes: the title of the question might be baiting people into thinking the question is lower quality than it really is. It doesn't really reflect what you're asking, and sounds like someone asking how to write IIFEs without looking it up first. – byxor Feb 03 '20 at 16:02
  • I didn't downvote it, but finding the answer imho looks pretty straight forward: open the spec, go to the related grammar rules, find out, why the parser is including the bracket after the closing curly into the token. Almost surely some ambiguity with a different syntax feature. – ASDFGerte Feb 03 '20 at 16:04
  • the pattern is such that, for the anonymous function declaration defined -> `(() => {})` should be immediately called with the following `()` another example could be `((item) => { // do something with item })(1)` – Denis Tsoi Feb 03 '20 at 16:04
  • 1
    Related: https://stackoverflow.com/questions/50461820/what-is-the-exact-parsing-precedence-of-arrow-function-fat-arrow-in-javascr –  Feb 03 '20 at 16:04
  • @ASDFGerte I'd argue that finding something specific without knowing where is should be defined in the spec can be a bit of a hassle – Seblor Feb 03 '20 at 16:05
  • @Seblor hence why i didn't downvote it. – ASDFGerte Feb 03 '20 at 16:05
  • 1
    Neither of the "duplicates" answer this question as far as I can see. – Ben Aston Feb 03 '20 at 16:09
  • 1
    The duplicates state "this is how you do it", not "this is why the language semantics require this" – Patrick Roberts Feb 03 '20 at 16:10
  • 1
    @ASDFGerte I'm not sure the spec will actually point out the ambiguity. It will merely define the grammar? – Ben Aston Feb 03 '20 at 16:15
  • My best guess is because there is nothing in the language grammar that defines an "arrow function _expression_". The static semantic [`IsFunctionDefinition`](http://www.ecma-international.org/ecma-262/#sec-assignment-operators-static-semantics-isfunctiondefinition) for `AssignmentExpression` always evaluates to `true` for `ArrowFunction` and `AsyncArrowFunction`, and a function definition is not callable. – Patrick Roberts Feb 03 '20 at 16:19
  • I was mostly commenting to "why is this getting downvoted". The issue is, that after knowing the immediate solution (put extra brackets), a question of "give me the parser details" imho raises the bar for own effort. As mentioned multiple times, i didn't downvote here, but i would have been much happier, if the question included attempts to read the related grammar, and find out, why this is happening, and where you got stuck there. I mean, that's what i am doing right now, reading the spec, searching for why it parses this way (cause curiosity killed the cat, you know :) ) – ASDFGerte Feb 03 '20 at 16:20
  • About the spec, yes, it likely will not have a "Note: you need to put extra brackets around arrow function IIFE because ...", but ambiguities in parsing a certain sequence are often obvious, when knowing every grammar rule related. – ASDFGerte Feb 03 '20 at 16:21
  • This is just a complex version of JFGI? – Ben Aston Feb 03 '20 at 16:21
  • 3
    "*What is the ambiguity?*" - it is when the arrow function does not have a block body but a concise body. [That's why you cannot use arrow functions as operands to many operators](https://stackoverflow.com/questions/50461820/what-is-the-exact-parsing-precedence-of-arrow-function-fat-arrow) – Bergi Feb 03 '20 at 16:22
  • Still trying to wrap my head around it. Don't currently understand how a block can be ambiguous with a concise body. – Ben Aston Feb 03 '20 at 16:25
  • So are you saying that `() => { console.log('') }` is never implicitly expressionized, and is always an arrow function declaration? If those words make sense. – Ben Aston Feb 03 '20 at 16:29
  • 2
    @Ben In short, `a = b = () => a = b = c` is valid and has resolved ambiguity through precedence rules. `a = () => b () () ()` is the same - and equal to `a = () => { return b()()(); }`, not to `a = (() => b)()()()`. This is why `() => { b() }` is not allowed in that position either, even if an arrow function with a block body wouldn't be ambiguous. – Bergi Feb 03 '20 at 16:30
  • 2
    @Ben Yes, it's always parsed as an arrow function expression, with the same grammar rules as a concise-body one. – Bergi Feb 03 '20 at 16:31
  • @Ben that's what _I_ was saying. I'm not quite sure if that's what Bergi was getting at, but his comment is definitely related. His focused on what ambiguity in the grammar is being avoided by not "expressionizing" it, while mine focused on where it shows it is never "expressionized". **edit** well, _now_ he's said it. – Patrick Roberts Feb 03 '20 at 16:31
  • @PatrickRoberts "*there is nothing in the language grammar that defines an "arrow function expression"*" - yes there is (although it might be hidden behind one of these ugly "cover grammar" things). The parse error has nothing to do with the arrow function being parsed as a declaration (those don't exist, it's always an expression). But yes, it's an `AssignmentExpression`, and they cannot appear inside a call expression. – Bergi Feb 03 '20 at 16:34
  • @Bergi nit: `/expression/definition`. ECMAScript never mentions an "arrow function expression". I realize I'm being pedantic, but there is an `ArrowFunction` expression, which is a valid grammar for an `AssignmentExpression`, but the respective section in ECMAScript uses the phrase "Arrow function definition" for defining the grammar of `ArrowFunction`. – Patrick Roberts Feb 03 '20 at 16:34
  • Sorry, I keep writing "declaration" where I mean to write "definition"... – Patrick Roberts Feb 03 '20 at 16:39
  • OK, so I now loosely understand the proximate grammar reasons, but I don't understand the "ultimate why". Is it to do with the order of lexing? `()=>{}` is famously ambiguous, but to a human `()=>{console.log('')}` is unambiguous. As we saying that the latter is also ambiguous to the parser? – Ben Aston Feb 03 '20 at 16:40
  • 1
    @Ben the ambiguity you're referring to is unrelated. It's solved by the grammar [`CoverParenthesizedExpressionAndArrowParameterList`](http://www.ecma-international.org/ecma-262/#prod-CoverParenthesizedExpressionAndArrowParameterList). Re-read [this comment](https://stackoverflow.com/questions/60042743/immediately-executed-anonymous-function-syntax-ambiguity#comment106190409_60042743) a few times and let it sink in. The ambiguity being solved is `() => b()` vs. `(() => b)()`, not `() => { b }` vs `() => ({ b })` – Patrick Roberts Feb 03 '20 at 16:46
  • How do you link to a comment BTW? – Ben Aston Feb 03 '20 at 16:51
  • 1
    https://meta.stackexchange.com/questions/5436/direct-link-to-a-comment – ASDFGerte Feb 03 '20 at 16:59
  • 1
    Unsure whether to post this here, or on your new (probably related) question. I am also still not exactly sure about the "why". It looks like CallExpression cannot have an arrow function, unless it's parenthesized. In other words, the chain CallExpression-PrimaryExpression-FunctionExpression exists, but for arrow functions, there is only the path over expressions in parenthesis. Don't see yet, why ConciseBody productions can't get their own names, and CallExpression-PrimaryExpression-ArrowFunctionWithBody (some new name) added. Still searching ~~~ – ASDFGerte Feb 03 '20 at 19:21
  • Can we get some reopen votes on this q please? – Ben Aston Feb 03 '20 at 19:27
  • @Ben tbh I would've marked it as a duplicate of https://stackoverflow.com/q/50461820/1048572 if it wasn't already closed – Bergi Feb 03 '20 at 19:44
  • It not a dupe of that because that q asks "what", this asks "why". – Ben Aston Feb 03 '20 at 19:45
  • My current interpretation of the question is: "Couldn't the grammar be changed, so arrow-functions with {FunctionBody} (not the ones with ExpressionBody) are added to the PrimaryExpression production (like function-expressions), without causing damage elsewhere?". I originally guessed, that it wasn't possible, because this would cause some unsolvable ambiguity. However, i now feel more and more, like it may have other reasons, perhaps even arbitrary ones (e.g. making the grammar/parsing unnecessarily more complex, or even just not having been considered yet, due to being unimportant). – ASDFGerte Feb 03 '20 at 20:23

0 Answers0