Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upDuplicate parameters of functions whose bodies are strict #632
Comments
bakkot
changed the title from
Strict mode, function code, and parameters
to
Duplicate parameters of functions whose bodies are strict
Jul 6, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
getify
Jul 6, 2016
Contributor
IANASA (I am not a spec author), but...
Function code is strict mode code if ... the code that produces the value of the function's [[ECMAScriptCode]] internal slot begins with a Directive Prologue that contains a Use Strict Directive.
I read that to say that the entire function ("function code") is considered strict if its body is strict (regardless of surrounding code). Therefore, I would assume the strict mode early error would apply to the param list of such a function.
Defining "function code" as "the entire function" is backed up by:
Function code is source text that is parsed to supply the value of the [[ECMAScriptCode]] and [[FormalParameters]] internal slots (see 9.2) of an ECMAScript function object.
IOW, "function code" is not just the body, but also its parameter list.
|
IANASA (I am not a spec author), but...
I read that to say that the entire function ("function code") is considered strict if its body is strict (regardless of surrounding code). Therefore, I would assume the strict mode early error would apply to the param list of such a function. Defining "function code" as "the entire function" is backed up by:
IOW, "function code" is not just the body, but also its parameter list. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bakkot
Jul 6, 2016
Contributor
@getify, that's approximately true, and the formal parameters are indeed strict mode code since they are a part of the function code.
However, the conditions for this Early Error to be applied are not that the FormalParameters are strict code, but rather
If the source code matching this production is strict mode code
where "this production" is the FunctionDeclaration production, which is not strict code as I read it.
Note that the FunctionDeclaration production includes a BindingIdentifier which is not "source text that is parsed to supply the value of the [[ECMAScriptCode]] and [[FormalParameters]] internal slots", and as such is not "function code" and therefore not strict mode code. As such, the full FunctionDeclaration production can't be either. I believe this is backed up by the discussion on the Bugzilla bug I linked.
|
@getify, that's approximately true, and the formal parameters are indeed strict mode code since they are a part of the function code. However, the conditions for this Early Error to be applied are not that the
where "this production" is the Note that the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Jul 6, 2016
Member
@bakkot The intent of that spec. language (I wrote it) is that function foo(a, a){'use strict'} produces an early error.
As @getify points out, the formal parameters are port of the "function code". Perhaps a clarify note would help.
Also see https://github.com/tc39/tc39-notes/blob/master/es7/2015-07/july-29.md#conclusionresolution for a change that was made in ES2016
|
@bakkot The intent of that spec. language (I wrote it) is that As @getify points out, the formal parameters are port of the "function code". Perhaps a clarify note would help. Also see https://github.com/tc39/tc39-notes/blob/master/es7/2015-07/july-29.md#conclusionresolution for a change that was made in ES2016 |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bakkot
Jul 6, 2016
Contributor
@allenwb, good to know that this is indeed intended to be an error. It still looks to me like this is not what the spec implies, for the reason I give above; namely, the condition for the error to be applied is not that the parameters are strict mode code but rather that the entire FunctionDeclaration production is strict mode code (which, from what I can tell, it is not), despite the unfortunate naming of StrictFormalParameters.
|
@allenwb, good to know that this is indeed intended to be an error. It still looks to me like this is not what the spec implies, for the reason I give above; namely, the condition for the error to be applied is not that the parameters are strict mode code but rather that the entire |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
FWIW, I agree with @bakkot's reading. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Jul 6, 2016
Member
The intended reading is the same as @getify 's. Since there is confusion about this, the spec. language should be improved. I probably used "source code matching" instead of "function code" out of concern for possible phasing issues.
|
The intended reading is the same as @getify 's. Since there is confusion about this, the spec. language should be improved. I probably used "source code matching" instead of "function code" out of concern for possible phasing issues. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jmdyck
Jul 6, 2016
Collaborator
The intended reading is the same as @getify 's.
(Except that @getify didn't supply a reading for the early error in question.)
I probably used "source code matching" instead of "function code" out of concern for possible phasing issues.
I don't think we'd need to reverse that choice. To achieve the intended effect for this early error, we could replace:
the source code matching this production is strict mode code
with:
the source code matching /FormalParameters/ is strict mode code
Note that there are three other early errors that use the problematic phrasing.
(Except that @getify didn't supply a reading for the early error in question.)
I don't think we'd need to reverse that choice. To achieve the intended effect for this early error, we could replace:
with:
Note that there are three other early errors that use the problematic phrasing. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Jul 6, 2016
Member
the source code matching /FormalParameters/ is strict mode code
That seems equally confusing since is may be the presence of a use strict directive in the FunctionBody that causes the FormalParameters to be strict mode code.
That seems equally confusing since is may be the presence of a |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jmdyck
Jul 6, 2016
Collaborator
I don't see why it'd be confusing: the wording clearly requires the reader to understand the circumstances that would cause FormalParameters to be strict mode code, and the link will send them straight to 10.2.1, where they should discover that one such circumstance is the presence of a USD in the FunctionBody. (And if you think that discovery wouldn't be obvious enough, then isn't that 10.2.1's problem?)
But we could equivalently say
the source code matching /FunctionBody/ is strict mode code
if you think that'd be less confusing.
|
I don't see why it'd be confusing: the wording clearly requires the reader to understand the circumstances that would cause FormalParameters to be strict mode code, and the link will send them straight to 10.2.1, where they should discover that one such circumstance is the presence of a USD in the FunctionBody. (And if you think that discovery wouldn't be obvious enough, then isn't that 10.2.1's problem?) But we could equivalently say
if you think that'd be less confusing. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nenionoda
Jul 7, 2016
Have I understood it correctly then, that FunctionDeclaration (especially including its BindingIdentifier) would be strict mode code if its FunctionBody is strict ( i.e., starts with a use strict directive)?
nenionoda
commented
Jul 7, 2016
|
Have I understood it correctly then, that FunctionDeclaration (especially including its BindingIdentifier) would be strict mode code if its FunctionBody is strict ( i.e., starts with a use strict directive)? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nenionoda
Jul 7, 2016
I do know the FormalParameters will be "strict"ly treated in presence of a use strict directive in FunctionBody. Below merely refers to my previous comment:
I'm becoming almost certain that I'm wrong, i.e., I'm almost believing that "the source text matching" a FunctionDeclaration (as a whole) will not be strict mode code if its corresponding FunctionBody contains a use strict. I'm especially asking this because I found this in the spec:
FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody}
FunctionDeclaration:function(FormalParameters){FunctionBody}
FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}
...
If the source code matching this production is strict mode code[<- when would it happen?], it is a Syntax Error if BindingIdentifier is the IdentifierName eval or the IdentifierName arguments.
I used to think this means that below would not be valid:
function eval() { "use strict;" }Then again though, I was told that a use strict directive only applies to the "function code", which is made up of the parameters and the function body only -- the BindingIdentifier has not been mentioned there.
This made me wonder for some time about what other cases would make "the source text matching" a FunctionDeclaration be strict mode code, and among the very few scenarios I found was when the FunctionDeclaration is directly contained in the body of a strict function, or is in a module, i.e., it is being parsed as a top level source element, with a source of type "module"; summing up:
function eval() {
"use strict"; // I used to think this would be an error; looks like I've been wrong
}
function eval() {
// ceratinly **not** an error
}function Strict() {
"use strict";
function eval() {
// will be an error, 'eval' is the 'BindingIdentifier' of this function,
// while it is surrounded by strict mode code
}
}To add to the confusion, take a look at these two, both from the spec:
Function code is strict mode code if the associated FunctionDeclaration, FunctionExpression,
GeneratorDeclaration, GeneratorExpression, MethodDefinition, or ArrowFunction is contained in strict mode code or if the code that produces the value of the function’s [[ECMAScriptCode]] internal slot begins with a Directive Prologue that contains a Use Strict Directive.
but
Function code is source text that is parsed to supply the value of the [[ECMAScriptCode]] and
[[FormalParameters]] internal slots (see 9.2) of an ECMAScript function object. The function code of a particular ECMAScript function does not include any source text that is parsed as the function code of a nested FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, ArrowFunction, ClassDeclaration, or ClassExpression.
Reading it again, The function code of a particular ECMAScript function does not include any source text that is parsed as the function code of a nested FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, ArrowFunction, ClassDeclaration, or ClassExpression.
In my humble opinion, the former quotation implies this must be an error:
function Strict() {
'use strict';
function HowShouldTheParamsBeTreatedNow(a,a) {} // should it be an error?
}The latter though, in my humble opinion, implies quite the contrary.
I hope I've been wrong believing I've been wrong.
nenionoda
commented
Jul 7, 2016
•
|
I do know the FormalParameters will be "strict"ly treated in presence of a use strict directive in FunctionBody. Below merely refers to my previous comment: I'm becoming almost certain that I'm wrong, i.e., I'm almost believing that "the source text matching" a FunctionDeclaration (as a whole) will not be strict mode code if its corresponding FunctionBody contains a use strict. I'm especially asking this because I found this in the spec:
I used to think this means that below would not be valid: function eval() { "use strict;" }Then again though, I was told that a use strict directive only applies to the "function code", which is made up of the parameters and the function body only -- the BindingIdentifier has not been mentioned there. This made me wonder for some time about what other cases would make "the source text matching" a FunctionDeclaration be strict mode code, and among the very few scenarios I found was when the FunctionDeclaration is directly contained in the body of a strict function, or is in a module, i.e., it is being parsed as a top level source element, with a source of type "module"; summing up: function eval() {
"use strict"; // I used to think this would be an error; looks like I've been wrong
}
function eval() {
// ceratinly **not** an error
}function Strict() {
"use strict";
function eval() {
// will be an error, 'eval' is the 'BindingIdentifier' of this function,
// while it is surrounded by strict mode code
}
}To add to the confusion, take a look at these two, both from the spec:
but
Reading it again, The function code of a particular ECMAScript function does not include any source text that is parsed as the function code of a nested FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, ArrowFunction, ClassDeclaration, or ClassExpression. In my humble opinion, the former quotation implies this must be an error: function Strict() {
'use strict';
function HowShouldTheParamsBeTreatedNow(a,a) {} // should it be an error?
}The latter though, in my humble opinion, implies quite the contrary. I hope I've been wrong believing I've been wrong. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jmdyck
Jul 7, 2016
Collaborator
To resolve the disagreement, I think you need to reconsider the conclusions you draw from the latter quotation. It's true that the parameter-list of the inner function is part of its function code, and not part of the function code of the outer function. But that doesn't prevent the strictness of the outer function from descending to the inner.
|
To resolve the disagreement, I think you need to reconsider the conclusions you draw from the latter quotation. It's true that the parameter-list of the inner function is part of its function code, and not part of the function code of the outer function. But that doesn't prevent the strictness of the outer function from descending to the inner. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jmdyck
Jul 7, 2016
Collaborator
Have I understood it correctly then, that FunctionDeclaration (especially including its BindingIdentifier) would be strict mode code if its FunctionBody is strict ( i.e., starts with a use strict directive)?
That's not what the spec says, but I gather that's how some implementations behave. It might help to read https://bugs.ecmascript.org/show_bug.cgi?id=4243
That's not what the spec says, but I gather that's how some implementations behave. It might help to read https://bugs.ecmascript.org/show_bug.cgi?id=4243 |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nenionoda
commented
Jul 7, 2016
|
@jmdyck Thanks a lot! I must stand corrected then :) |
bakkot
referenced this issue
Feb 5, 2018
Closed
Normative: Expand text included in "function code" #1091
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jugglinmike
Mar 18, 2018
Contributor
@bakkot It seems like your reading and @jmdyck's proposed modification are in-line with both implementations and the intent of the original author (for what it's worth: I prefer the second phrasing). If that's right, then we already have consensus and can move forward with the patch to the spec. Would either you or @jmdyck like to file a pull request? I'd be happy to do the honors if that would be helpful--let me know.
|
@bakkot It seems like your reading and @jmdyck's proposed modification are in-line with both implementations and the intent of the original author (for what it's worth: I prefer the second phrasing). If that's right, then we already have consensus and can move forward with the patch to the spec. Would either you or @jmdyck like to file a pull request? I'd be happy to do the honors if that would be helpful--let me know. |
bakkot commentedJul 6, 2016
It looks to me that function declarations whose bodies are strict but which are not within strict code are permitted to have duplicated parameter names, and I suspect this is a mistake.
We have the following partial definition for strict mode code:
We also have these Early Errors for FunctionDeclarations:
As I read this, "the source code matching this production [i.e.
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }]" is not strict mode code just because its body contains a Use Strict Directive; only theFormalParametersandFunctionBodyparts are. As such, the the Early Error rules forStrictFormalParameters : FormalParametersare not applied.Hence, a Script like
function foo(a, a){'use strict'}would not have any Early Errors.This seems wrong, and implementations do indeed enforce this Early Error. Either way, I think it would be good to have a NOTE here clarifying whether the strict-mode Early Errors for parameters and function names are intended to apply to function declarations (and expressions) which contain a Use Strict Directive but are not themselves inside of strict mode code.
See related issue previously. (Also, when are we going to get the Bugzilla cert fixed?)