function finally() {} in Safari gives "SyntaxError: Cannot use the keyword 'finally' as a function name.", v8 and Firefox give a similar error.
Is there any reason why this couldn't be made legal? I can do var obj = { finally() {} } just fine. Similarly, var finally doesn't work.
It seems in the post-ES5 tradition to reduce magically forbidden variable and function names :-) Thoughts?
(https://github.com/ljharb/proposal-promise-finally/issues/4)
Wouldn't a finally function result in problems with ASI? E.g. consider this snippet:
try
{
console.log('try');
throw new Error('error');
}
finally
{
console.log('finally');
}
This would currently be considered to be a normal try-finally block, and thus log
finally
However, if finally is _not_ a forbidden name then finally would be considered to be an expression statement instead, followed by a block statement, in which case the block statement would _not_ be executed if an error is thrown.
I'm not sure how it would cause an issue with ASI in the function finally( case - i can't see how the word "finally" there, after the function keyword and before a (, could be in statement position.
You might be completely right about the variable name, and also about the lexical name reference inside the function.
I might have worded it poorly, the problem is not with the function declaration, but with the usage of the word finally in the try-(catch-)finally construct. I think _without_ the reserved finally keyword ASI would transform my snippet into this:
try
{
console.log('try');
throw new Error('error');
};
finally; //<-- problem here
{
console.log('finally');
};
I agree it needs to be reserved in a statement context - however it seems like the grammar should be able to allow it as a static function name, since there's no ambiguity there.
I might have worded it poorly, the problem is not with the function declaration, but with the usage of the word finally in the try-(catch-)finally construct. I think without the reserved finally keyword ASI would transform my snippet into this:
No, because ASI only applies only when it would be a syntax error when not introducing the semicolon.
In particular, since
try { /*... */ }
finally
{ /* ... */ }
is perfectly valid there is no inserted semicolon.
However, in the following case, an implicit semicolon could be inserted, because otherwise it would be a syntax error:
anything();
finally // <-- here
{ /* ... */ }
If you unconditionally unreserve finally, you just need a lookahead in order to distinguish:
try { }
finally();
from:
try { }
finally { }
Not a difficult problem, but another small complication in the grammar.
If you keep finally reserved in statement context only (I wouldn鈥檛 recommend it), the following code would unintuitively be invalid:
finally();
you just need a lookahead
Finally, looking at the current grammar, you probably don鈥檛 need a lookahead.
The same problem with function finally also happens with function catch, and supporting that last one seems complicated...
IIUC, unless you plan to also allow var catch and var finally, you could just allow the name (e.g. for identification in stack traces) but prevent it from entering scope, restricting it only to non-self-referential function expressions.
That's exactly what I'm asking for. I want the name to be syntactically valid, even if it creates no lexical binding.
This is not the place to make proposals turning keywords into pseudo-keywords.
Most helpful comment
No, because ASI only applies only when it would be a syntax error when not introducing the semicolon.
In particular, since
is perfectly valid there is no inserted semicolon.
However, in the following case, an implicit semicolon could be inserted, because otherwise it would be a syntax error: