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

Non-concise function can not statically have name "finally", `var finally` fails too #580

Closed
ljharb opened this Issue May 23, 2016 · 10 comments

Comments

Projects
None yet
5 participants
@ljharb
Member

ljharb commented May 23, 2016

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?

(tc39/proposal-promise-finally#4)

@TiddoLangerak

This comment has been minimized.

Show comment
Hide comment
@TiddoLangerak

TiddoLangerak May 23, 2016

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

try
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.

TiddoLangerak commented May 23, 2016

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

try
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.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb May 23, 2016

Member

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.

Member

ljharb commented May 23, 2016

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.

@TiddoLangerak

This comment has been minimized.

Show comment
Hide comment
@TiddoLangerak

TiddoLangerak May 23, 2016

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');
};

TiddoLangerak commented May 23, 2016

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');
};
@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb May 23, 2016

Member

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.

Member

ljharb commented May 23, 2016

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.

@claudepache

This comment has been minimized.

Show comment
Hide comment
@claudepache

claudepache May 23, 2016

Contributor

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
{ /* ... */ }
Contributor

claudepache commented May 23, 2016

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
{ /* ... */ }
@claudepache

This comment has been minimized.

Show comment
Hide comment
@claudepache

claudepache May 23, 2016

Contributor

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’t recommend it), the following code would unintuitively be invalid:

finally();
Contributor

claudepache commented May 23, 2016

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’t recommend it), the following code would unintuitively be invalid:

finally();
@claudepache

This comment has been minimized.

Show comment
Hide comment
@claudepache

claudepache May 23, 2016

Contributor

you just need a lookahead

Finally, looking at the current grammar, you probably don’t need a lookahead.

Contributor

claudepache commented May 23, 2016

you just need a lookahead

Finally, looking at the current grammar, you probably don’t need a lookahead.

@Kovensky

This comment has been minimized.

Show comment
Hide comment
@Kovensky

Kovensky Jun 24, 2016

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.

Kovensky commented Jun 24, 2016

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.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Jun 24, 2016

Member

That's exactly what I'm asking for. I want the name to be syntactically valid, even if it creates no lexical binding.

Member

ljharb commented Jun 24, 2016

That's exactly what I'm asking for. I want the name to be syntactically valid, even if it creates no lexical binding.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Sep 12, 2016

Member

This is not the place to make proposals turning keywords into pseudo-keywords.

Member

bterlson commented Sep 12, 2016

This is not the place to make proposals turning keywords into pseudo-keywords.

@bterlson bterlson closed this Sep 12, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment