Specification of use before declaration errors
On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote:
That is, consider this code:
function f() { { var x = 5; let x;
declaring the same name using a let and a var is an early error: people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors or for the function level people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors
I think the var declaration creates a binding for x in the function’s lexical environment, but then binds to the x in the block’s environment for the initialization. As such, the initialization should throw a “use before declaration” error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here?
because an early error exists, the surround script or module is never evaluated.
On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote: > Hello es-discuss, > > I’m having difficulty figuring out where the ES6 draft spec specifies that a “use before declaration” error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a “use before declaration” error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. > > That is, consider this code: > > function f() { > { > var x = 5; > let x; declaring the same name using a let and a var is an early error: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors or for the function level http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors > } > } > > f(); > > I think the var declaration creates a binding for x in the function’s lexical environment, but then binds to the x in the block’s environment for the initialization. As such, the initialization should throw a “use before declaration” error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? because an early error exists, the surround script or module is never evaluated. Allen -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131108/5f01edd6/attachment.html>
Wait, so is there no variable shadowing allowed then?
13.1.1 Static Semantics: Early Errors
Block : { StatementList }
It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries.
It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames of StatementList.
StatementList can contain Blocks whose LexicallyDeclaredNames and VarDeclaredNames algorithms return the values for their StatementLists, so it recursively collects the names from all nested lexical and var declarations.
It looks like VarDeclaredNames is missing a definition for VariableStatement because I can't see any way for the bound names of a VariableStatement to get added to VarDeclaredNames lists.
But barring for the moment that I cannot find an algorithm definition that adds BoundNames of a VariableStatement to VarDeclaredNames, this second early error bullet implies that shadowing of bound names is not allowed at all.
Is this correct?
Wait, so is there no variable shadowing allowed then? 13.1.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors> Static Semantics: Early Errors Block : { StatementList } * It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries. * It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames of StatementList. StatementList can contain Blocks whose LexicallyDeclaredNames and VarDeclaredNames algorithms return the values for their StatementLists, so it recursively collects the names from all nested lexical and var declarations. It looks like VarDeclaredNames is missing a definition for VariableStatement because I can't see any way for the bound names of a VariableStatement to get added to VarDeclaredNames lists. But barring for the moment that I cannot find an algorithm definition that adds BoundNames of a VariableStatement to VarDeclaredNames, this second early error bullet implies that shadowing of bound names is not allowed at all. Is this correct? Ian From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] Sent: Friday, November 8, 2013 4:16 PM To: Ian Halliday Cc: es-discuss at mozilla.org Subject: Re: Specification of use before declaration errors On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote: Hello es-discuss, I'm having difficulty figuring out where the ES6 draft spec specifies that a "use before declaration" error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a "use before declaration" error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. That is, consider this code: function f() { { var x = 5; let x; declaring the same name using a let and a var is an early error: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors or for the function level http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors } } f(); I think the var declaration creates a binding for x in the function's lexical environment, but then binds to the x in the block's environment for the initialization. As such, the initialization should throw a "use before declaration" error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? because an early error exists, the surround script or module is never evaluated. Allen -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131113/d7a6a093/attachment-0001.html>
On Nov 13, 2013, at 3:41 PM, Ian Halliday wrote:
Wait, so is there no variable shadowing allowed then?
this is saying that things like the following are illegal:
{var x;
let x;
}
But shadowing, like the following is fine:
var x;
{let x;
}
On Nov 13, 2013, at 3:41 PM, Ian Halliday wrote: > Wait, so is there no variable shadowing allowed then? this is saying that things like the following are illegal: {var x; let x; } But shadowing, like the following is fine: var x; {let x; } > > 13.1.1 Static Semantics: Early Errors > > Block : { StatementList } > · It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries. > > · It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames ofStatementList. > > StatementList can contain Blocks whose LexicallyDeclaredNames and VarDeclaredNames algorithms return the values for their StatementLists, so it recursively collects the names from all nested lexical and var declarations. > > It looks like VarDeclaredNames is missing a definition for VariableStatement because I can’t see any way for the bound names of a VariableStatement to get added to VarDeclaredNames lists. > > But barring for the moment that I cannot find an algorithm definition that adds BoundNames of a VariableStatement to VarDeclaredNames, this second early error bullet implies that shadowing of bound names is not allowed at all. > > Is this correct? > > Ian > > > From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] > Sent: Friday, November 8, 2013 4:16 PM > To: Ian Halliday > Cc: es-discuss at mozilla.org > Subject: Re: Specification of use before declaration errors > > > On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote: > > > Hello es-discuss, > > I’m having difficulty figuring out where the ES6 draft spec specifies that a “use before declaration” error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a “use before declaration” error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. > > > > That is, consider this code: > > function f() { > { > var x = 5; > let x; > declaring the same name using a let and a var is an early error: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors > or for the function level http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors > > > > } > } > > f(); > > I think the var declaration creates a binding for x in the function’s lexical environment, but then binds to the x in the block’s environment for the initialization. As such, the initialization should throw a “use before declaration” error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? > > because an early error exists, the surround script or module is never evaluated. > > Allen -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131113/a66a0e80/attachment.html>
Then for 13.1.8 shouldn't there be something like this
StatementListItem : Statement
1. If Statement is a Block then return a new empty List.
2. Else return VarDeclaredNames of Statement
defined in order to prevent the var names from spreading into enclosing blocks?
I might be misunderstanding VarDeclaredNames. I am guessing that it should be a collection of all the names declared via var declaration statements, i.e. VariableStatement, but there isn't a definition of VarDeclaredNames for VariableStatement.
Then for 13.1.8 shouldn't there be something like this StatementListItem : Statement 1. If Statement is a Block then return a new empty List. 2. Else return VarDeclaredNames of Statement defined in order to prevent the var names from spreading into enclosing blocks? I might be misunderstanding VarDeclaredNames. I am guessing that it should be a collection of all the names declared via var declaration statements, i.e. VariableStatement, but there isn't a definition of VarDeclaredNames for VariableStatement. 13.1.8<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-vardeclarednames> Static Semantics: VarDeclaredNames See also: 13.0.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-statement-semantics-static-semantics-vardeclarednames>, 13.5.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-if-statement-static-semantics-vardeclarednames>, 13.6.1.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-do-while-statement-static-semantics-vardeclarednames>, 13.6.2.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-while-statement-static-semantics-vardeclarednames>, 13.6.3.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-for-statement-static-semantics-vardeclarednames>, 13.6.4.3<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-for-in-and-for-of-statements-static-semantics-vardeclarednames>, 13.10.2<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-with-statement-static-semantics-vardeclarednames>, 13.11.4<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-switch-statement-static-semantics-vardeclarednames>, 13.12.2<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-labelled-statements-static-semantics-vardeclarednames>, 13.14.2<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-try-statement-static-semantics-vardeclarednames>, 14.1.11<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-vardeclarednames>, 14.4.10<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generator-function-definitions-static-semantics-vardeclarednames>, 14.5.14<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-class-definitions-static-semantics-vardeclarednames>, 15.1.0.12<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-module-semantics-static-semantics-vardeclarednames>, 15.2.5<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-scripts-static-semantics-vardeclarednames>. Block : { } 1. Return a new empty List<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-list-and-record-specification-type>. StatementList : StatementList StatementListItem 1. Let names be VarDeclaredNames of StatementList. 2. Append to names the elements of the VarDeclaredNames of StatementListItem. 3. Return names. StatementListItem : Declaration 1. Return a new empty List<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-list-and-record-specification-type>. From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] Sent: Wednesday, November 13, 2013 3:49 PM To: Ian Halliday Cc: es-discuss at mozilla.org Subject: Re: Specification of use before declaration errors On Nov 13, 2013, at 3:41 PM, Ian Halliday wrote: Wait, so is there no variable shadowing allowed then? this is saying that things like the following are illegal: {var x; let x; } But shadowing, like the following is fine: var x; {let x; } 13.1.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors> Static Semantics: Early Errors Block : { StatementList } * It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries. * It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames ofStatementList. StatementList can contain Blocks whose LexicallyDeclaredNames and VarDeclaredNames algorithms return the values for their StatementLists, so it recursively collects the names from all nested lexical and var declarations. It looks like VarDeclaredNames is missing a definition for VariableStatement because I can't see any way for the bound names of a VariableStatement to get added to VarDeclaredNames lists. But barring for the moment that I cannot find an algorithm definition that adds BoundNames of a VariableStatement to VarDeclaredNames, this second early error bullet implies that shadowing of bound names is not allowed at all. Is this correct? Ian From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] Sent: Friday, November 8, 2013 4:16 PM To: Ian Halliday Cc: es-discuss at mozilla.org<mailto:es-discuss at mozilla.org> Subject: Re: Specification of use before declaration errors On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote: Hello es-discuss, I'm having difficulty figuring out where the ES6 draft spec specifies that a "use before declaration" error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a "use before declaration" error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. That is, consider this code: function f() { { var x = 5; let x; declaring the same name using a let and a var is an early error: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors or for the function level http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors } } f(); I think the var declaration creates a binding for x in the function's lexical environment, but then binds to the x in the block's environment for the initialization. As such, the initialization should throw a "use before declaration" error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? because an early error exists, the surround script or module is never evaluated. Allen -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131114/b20a51e2/attachment-0001.html>
Oh, is "shadowing" a let declaration with a var declaration a syntax error? E.g.
{
let x;
{
var x;
}
}
Oh, is "shadowing" a let declaration with a var declaration a syntax error? E.g. { let x; { var x; } } From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Ian Halliday Sent: Wednesday, November 13, 2013 4:14 PM To: Allen Wirfs-Brock Cc: es-discuss at mozilla.org Subject: RE: Specification of use before declaration errors Then for 13.1.8 shouldn't there be something like this StatementListItem : Statement 1. If Statement is a Block then return a new empty List. 2. Else return VarDeclaredNames of Statement defined in order to prevent the var names from spreading into enclosing blocks? I might be misunderstanding VarDeclaredNames. I am guessing that it should be a collection of all the names declared via var declaration statements, i.e. VariableStatement, but there isn't a definition of VarDeclaredNames for VariableStatement. 13.1.8<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-vardeclarednames> Static Semantics: VarDeclaredNames See also: 13.0.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-statement-semantics-static-semantics-vardeclarednames>, 13.5.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-if-statement-static-semantics-vardeclarednames>, 13.6.1.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-do-while-statement-static-semantics-vardeclarednames>, 13.6.2.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-while-statement-static-semantics-vardeclarednames>, 13.6.3.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-for-statement-static-semantics-vardeclarednames>, 13.6.4.3<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-for-in-and-for-of-statements-static-semantics-vardeclarednames>, 13.10.2<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-with-statement-static-semantics-vardeclarednames>, 13.11.4<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-switch-statement-static-semantics-vardeclarednames>, 13.12.2<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-labelled-statements-static-semantics-vardeclarednames>, 13.14.2<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-try-statement-static-semantics-vardeclarednames>, 14.1.11<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-vardeclarednames>, 14.4.10<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generator-function-definitions-static-semantics-vardeclarednames>, 14.5.14<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-class-definitions-static-semantics-vardeclarednames>, 15.1.0.12<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-module-semantics-static-semantics-vardeclarednames>, 15.2.5<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-scripts-static-semantics-vardeclarednames>. Block : { } 1. Return a new empty List<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-list-and-record-specification-type>. StatementList : StatementList StatementListItem 1. Let names be VarDeclaredNames of StatementList. 2. Append to names the elements of the VarDeclaredNames of StatementListItem. 3. Return names. StatementListItem : Declaration 1. Return a new empty List<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-list-and-record-specification-type>. From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] Sent: Wednesday, November 13, 2013 3:49 PM To: Ian Halliday Cc: es-discuss at mozilla.org<mailto:es-discuss at mozilla.org> Subject: Re: Specification of use before declaration errors On Nov 13, 2013, at 3:41 PM, Ian Halliday wrote: Wait, so is there no variable shadowing allowed then? this is saying that things like the following are illegal: {var x; let x; } But shadowing, like the following is fine: var x; {let x; } 13.1.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors> Static Semantics: Early Errors Block : { StatementList } * It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries. * It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames ofStatementList. StatementList can contain Blocks whose LexicallyDeclaredNames and VarDeclaredNames algorithms return the values for their StatementLists, so it recursively collects the names from all nested lexical and var declarations. It looks like VarDeclaredNames is missing a definition for VariableStatement because I can't see any way for the bound names of a VariableStatement to get added to VarDeclaredNames lists. But barring for the moment that I cannot find an algorithm definition that adds BoundNames of a VariableStatement to VarDeclaredNames, this second early error bullet implies that shadowing of bound names is not allowed at all. Is this correct? Ian From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] Sent: Friday, November 8, 2013 4:16 PM To: Ian Halliday Cc: es-discuss at mozilla.org<mailto:es-discuss at mozilla.org> Subject: Re: Specification of use before declaration errors On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote: Hello es-discuss, I'm having difficulty figuring out where the ES6 draft spec specifies that a "use before declaration" error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a "use before declaration" error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. That is, consider this code: function f() { { var x = 5; let x; declaring the same name using a let and a var is an early error: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors or for the function level http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors } } f(); I think the var declaration creates a binding for x in the function's lexical environment, but then binds to the x in the block's environment for the initialization. As such, the initialization should throw a "use before declaration" error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? because an early error exists, the surround script or module is never evaluated. Allen -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131114/6a859e44/attachment-0001.html>
On Nov 13, 2013, at 4:13 PM, Ian Halliday wrote:
Then for 13.1.8 shouldn’t there be something like this
StatementListItem : Statement 1. If Statement is a Block then return a new empty List. 2. Else return VarDeclaredNames of Statement
defined in order to prevent the var names from spreading into enclosing blocks?
I might be misunderstanding VarDeclaredNames. I am guessing that it should be a collection of all the names declared via var declaration statements, i.e.VariableStatement, but there isn’t a definition of VarDeclaredNames for VariableStatement.
VarDeclaredNames are hoisted to the top level (function or script) and it is illegal to hoist a VarDeclaredName past a lexical declaration for the same named. "It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames ofStatementList." is saying that if any name that has is immediately declared within this block cannot also occur in a var declaration either immediately in this block or in many nested block (to any level of nesting).
The hoisting is handled in the definitions of LexicallyDeclaredNames
On Nov 13, 2013, at 4:13 PM, Ian Halliday wrote: > Then for 13.1.8 shouldn’t there be something like this > > StatementListItem : Statement > 1. If Statement is a Block then return a new empty List. > 2. Else return VarDeclaredNames of Statement > defined in order to prevent the var names from spreading into enclosing blocks? > > I might be misunderstanding VarDeclaredNames. I am guessing that it should be a collection of all the names declared via var declaration statements, i.e.VariableStatement, but there isn’t a definition of VarDeclaredNames for VariableStatement. VarDeclaredNames are hoisted to the top level (function or script) and it is illegal to hoist a VarDeclaredName past a lexical declaration for the same named. "It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames ofStatementList." is saying that if any name that has is immediately declared within this block cannot also occur in a var declaration either immediately in this block or in many nested block (to any level of nesting). The hoisting is handled in the definitions of LexicallyDeclaredNames > 13.1.8 Static Semantics: VarDeclaredNames > > See also: 13.0.1, 13.5.1, 13.6.1.1, 13.6.2.1, 13.6.3.1, 13.6.4.3, 13.10.2, 13.11.4, 13.12.2, 13.14.2, 14.1.11, 14.4.10, 14.5.14, 15.1.0.12, 15.2.5. > > Block : { } > 1. Return a new empty List. > StatementList : StatementList StatementListItem > 1. Let names be VarDeclaredNames of StatementList. > 2. Append to names the elements of the VarDeclaredNames of StatementListItem. > 3. Return names. > StatementListItem : Declaration > 1. Return a new empty List. > > > > From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] > Sent: Wednesday, November 13, 2013 3:49 PM > To: Ian Halliday > Cc: es-discuss at mozilla.org > Subject: Re: Specification of use before declaration errors > > > On Nov 13, 2013, at 3:41 PM, Ian Halliday wrote: > > > Wait, so is there no variable shadowing allowed then? > > this is saying that things like the following are illegal: > > {var x; > let x; > } > > But shadowing, like the following is fine: > > var x; > {let x; > } > > > > > > 13.1.1 Static Semantics: Early Errors > > Block : { StatementList } > · It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries. > > · It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames ofStatementList. > > StatementList can contain Blocks whose LexicallyDeclaredNames and VarDeclaredNames algorithms return the values for their StatementLists, so it recursively collects the names from all nested lexical and var declarations. > > It looks like VarDeclaredNames is missing a definition for VariableStatement because I can’t see any way for the bound names of a VariableStatement to get added to VarDeclaredNames lists. > > But barring for the moment that I cannot find an algorithm definition that adds BoundNames of a VariableStatement to VarDeclaredNames, this second early error bullet implies that shadowing of bound names is not allowed at all. > > Is this correct? > > Ian > > > From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] > Sent: Friday, November 8, 2013 4:16 PM > To: Ian Halliday > Cc: es-discuss at mozilla.org > Subject: Re: Specification of use before declaration errors > > > On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote: > > > > Hello es-discuss, > > I’m having difficulty figuring out where the ES6 draft spec specifies that a “use before declaration” error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a “use before declaration” error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. > > > > That is, consider this code: > > function f() { > { > var x = 5; > let x; > declaring the same name using a let and a var is an early error: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors > or for the function level http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors > > > > > } > } > > f(); > > I think the var declaration creates a binding for x in the function’s lexical environment, but then binds to the x in the block’s environment for the initialization. As such, the initialization should throw a “use before declaration” error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? > > because an early error exists, the surround script or module is never evaluated. > > Allen > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131113/6471571d/attachment-0001.html>
On Nov 13, 2013, at 4:18 PM, Ian Halliday wrote:
Oh, is “shadowing” a let declaration with a var declaration a syntax error? E.g.
yes, although strictly speaking it is the hoisting of the var over the let that is an error. Amounts to the same thing.
On Nov 13, 2013, at 4:18 PM, Ian Halliday wrote: > Oh, is “shadowing” a let declaration with a var declaration a syntax error? E.g. yes, although strictly speaking it is the hoisting of the var over the let that is an error. Amounts to the same thing. > > { > let x; > { > var x; > } > } > > From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Ian Halliday > Sent: Wednesday, November 13, 2013 4:14 PM > To: Allen Wirfs-Brock > Cc: es-discuss at mozilla.org > Subject: RE: Specification of use before declaration errors > > Then for 13.1.8 shouldn’t there be something like this > > StatementListItem : Statement > 1. If Statement is a Block then return a new empty List. > 2. Else return VarDeclaredNames of Statement > > defined in order to prevent the var names from spreading into enclosing blocks? > > I might be misunderstanding VarDeclaredNames. I am guessing that it should be a collection of all the names declared via var declaration statements, i.e. VariableStatement, but there isn’t a definition of VarDeclaredNames for VariableStatement. > 13.1.8 Static Semantics: VarDeclaredNames > > See also: 13.0.1, 13.5.1, 13.6.1.1, 13.6.2.1, 13.6.3.1, 13.6.4.3, 13.10.2, 13.11.4, 13.12.2, 13.14.2, 14.1.11, 14.4.10, 14.5.14, 15.1.0.12, 15.2.5. > > Block : { } > 1. Return a new empty List. > StatementList : StatementList StatementListItem > 1. Let names be VarDeclaredNames of StatementList. > 2. Append to names the elements of the VarDeclaredNames of StatementListItem. > 3. Return names. > StatementListItem : Declaration > 1. Return a new empty List. > > > > From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] > Sent: Wednesday, November 13, 2013 3:49 PM > To: Ian Halliday > Cc: es-discuss at mozilla.org > Subject: Re: Specification of use before declaration errors > > > On Nov 13, 2013, at 3:41 PM, Ian Halliday wrote: > > > Wait, so is there no variable shadowing allowed then? > > this is saying that things like the following are illegal: > > {var x; > let x; > } > > But shadowing, like the following is fine: > > var x; > {let x; > } > > > > > > 13.1.1 Static Semantics: Early Errors > > Block : { StatementList } > · It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries. > > · It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames ofStatementList. > > StatementList can contain Blocks whose LexicallyDeclaredNames and VarDeclaredNames algorithms return the values for their StatementLists, so it recursively collects the names from all nested lexical and var declarations. > > It looks like VarDeclaredNames is missing a definition for VariableStatement because I can’t see any way for the bound names of a VariableStatement to get added to VarDeclaredNames lists. > > But barring for the moment that I cannot find an algorithm definition that adds BoundNames of a VariableStatement to VarDeclaredNames, this second early error bullet implies that shadowing of bound names is not allowed at all. > > Is this correct? > > Ian > > > From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com] > Sent: Friday, November 8, 2013 4:16 PM > To: Ian Halliday > Cc: es-discuss at mozilla.org > Subject: Re: Specification of use before declaration errors > > > On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote: > > > > Hello es-discuss, > > I’m having difficulty figuring out where the ES6 draft spec specifies that a “use before declaration” error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a “use before declaration” error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. > > > > That is, consider this code: > > function f() { > { > var x = 5; > let x; > declaring the same name using a let and a var is an early error: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors > or for the function level http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors > > > > > } > } > > f(); > > I think the var declaration creates a binding for x in the function’s lexical environment, but then binds to the x in the block’s environment for the initialization. As such, the initialization should throw a “use before declaration” error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? > > because an early error exists, the surround script or module is never evaluated. > > Allen > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131113/5d0c0c92/attachment-0001.html>
I'm having difficulty figuring out where the ES6 draft spec specifies that a "use before declaration" error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a "use before declaration" error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError.
That is, consider this code:
function f() { { var x = 5; let x; } } f();
I think the var declaration creates a binding for x in the function's lexical environment, but then binds to the x in the block's environment for the initialization. As such, the initialization should throw a "use before declaration" error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here?
If I am not wrong then this raises the question of order of operations. Is the RHS evaluated first, then the error is thrown? Or is the LHS name evaluated first, throwing if it is a binding that is currently in its TDZ?
E.g. is g() called here before throwing?
function g() { console.log('hello'); return 0; } function f() { { var x = g(); let x; } } f();
How about for-in/of loops? Is g() called here?
function g() { console.log('hello'); return { a: 1, b: 2, c: 3 }; } function f() { { for (var x in g()) { console.log('unreachable'); } let x; } }