On Oct 22, 2012, at 5:27 AM, Rick Waldron wrote:
>
> On Monday, October 22, 2012 at 1:04 AM, Domenic Denicola wrote:
>
>> Thanks for your help Rick! I've corrected a few, but wasn't sure about some
>> others. Let me know if I'm missing something in the following:
>>
>> From: Rick Waldron [mailto:[email protected]]
>> Sent: Sunday, October 21, 2012 17:07
>>
>>> nit: The comment itself says "// error! used a `let` before declaration.",
>>> might be nice to highlight that the error will occur until the let is
>>> assigned, ie. I can initialize it, but reads will throw until it's assigned.
>>
>> If I'm understanding you correctly, you're saying that this should throw?
>>
>> let x;
>> assert(x === undefined); // error! Use of `x` before it is assigned.
> yes, any read access will throw before assignment.
>>
>> I was under the impression the temporal dead zone was about
>> use-before-definition, not use-before-assignment.
> There is no deadzone in the former, it's use-before-assignment
>
No, Domenic is correct. It is "use before initialization". Let bindings that
lack an initializer have an implicit "=undefined" initializer.
>> (For const they are the same, since the "Static Semantics: Early Errors"
>> note on page 125 of the spec gives a Syntax Error if the Initialiser is
>> omitted from the LexicalBinding.) That is:
>>
>> "A let and const declarations define variables that are scoped to the
>> running execution context’s LexicalEnvironment. The variables are created
>> when their containing Lexical Environment is instantiated but may not be
>> accessed in any way until the variable’s LexicalBinding is evaluated. A
>> variable defined by a LexicalBinding with an Initialiser is assigned the
>> value of its Initialiser’s AssignmentExpression when the LexicalBinding is
>> evaluated, not when the variable is created. If a LexicalBinding in a let
>> declaration does not have an an Initialiser the variable is assigned the
>> value undefined when the LexicalBinding is evaluated."
A missing initializer in a const declaration is defined as syntax error by the
first Early Error rule in section 12.2.1 which is for the production
LexicalBinding : BindingIdentifier
The note quoted above is an informative note and not normative language. What
it describes is accurate but is expressed in a more precise, but less
centralized manner by the normative algorithms and rules of the specification,
>>
>> This implies to me that the first line above evaluates the LexicalBinding,
>> assigning the variable the value undefined; since the LexicalBinding is
>> evaluated, the "may not be accessed" clause no longer applies, and no error
>> should occur.
>
> I'm not sure the full temporal deadzone semantics are even in a draft yet
> (like lots of things)
Yes, it's are all there, at least for function level declarations. Of course,
there could be errors so read deeply...
The global scope will be in the next draft.
>>
>>
>>> Not sure of the number, but there is a slide titled "Block Scoping" with
>>> this:
>>
>>> if (Math.random() > 0.5) {
>>> function go() {
>>> console.log("gone!");
>>> }
>>> ...
>>> }
>>> assert(typeof go === "undefined");
>>
>>> I'm not sure I get what this one is trying to illustrate, because "go" will
>>> always be initialized, regardless of the condition
>>
>> I believe this is not true. The current semantics for block-scoped functions
>> bind them to the block, not to the surrounding function. (That is, a
>> FunctionDeclaration creates an entry into LexicallyDeclaredNames, not into
>> VarDeclaredNames.)
>> Even in ES5, this behavior is unspecified: see the "NOTE" under the
>> "Semantics" heading under section 12 of ES5.1, where it notes that even
>> though Statement does not include FunctionDeclaration, implementations often
>> allow it, with "significant and irreconcilable variations." (So, I don't
>> think "go" will always be initialized in all browsers. For example, in IE10
>> strict mode the above code is a SyntaxError.) It also says that "Future
>> editions of ECMAScript may define alternative portable means for declaring
>> functions in a Statement context."
>>
>> And indeed, in ES6 the Declaration grammar production is introduced as a
>> sibling to Statement under Block. It includes LexicalDeclaration and
>> FunctionDeclaration; VariableStatements are left under Statement. And the
>> Block Declaration Instantiation algorithm (10.5.4) includes both
>> LexicalDeclarations and FunctionDeclarations, i.e. FunctionDeclarations are
>> added to the block's Declarative Environment Record instead of to the
>> environment record of the containing function.
Yes, function declarations are block scoped and are not hoisted to the
surrounding function.
In the above example, the asset is outside the block that defines go, so the
declaration is invisible. so, result is going to be just like ES5: either a
Reference Error or undefined, depending upon rather it is strict mode or not.
>>
>>> new Set(...document.body.children);
>>
>>> is a Syntax Error, use:
>>
>>> new Set([ ...document.body.children ]);
>>
>>> Same for:
>>> new Set(...array)
>>> Math.max(...array);
>>> Math.max(0, ...array, 5, ...array2);
>>> new Date(...dateFields);
>>> array.push(...array2);
>>
>> I don't think any of these is a syntax error, since spread works for
>> function calls/constructs too. See http://tc39wiki.calculist.org/es6/spread/
>> or section 11.2.5 of the draft spec wherein the expanded runtime semantics
>> for ArgumentListEvaluation are given (in particular ArgumentList:
>> ...AssignmentExpression and ArgumentList: ArgumentList,
>> ...AssignmentExpression). However, you are right that the sets should be
>> constructed that way, since the Set constructor accepts an iterable and not
>> varargs. Much appreciated!
> Not according to SpiderMonkey, so someone has a bug.
I just (yesterday) wrote the spec. language for Set and it takes a single
optional iterable argument. I don't see anything on the TC39 wiki to suggest
otherwise. We can't have a single method/function that is overloaded with both
a rest parameter and single iterable as the iterable case would look like a
single element rest. Given that we are using iterable at a number of places to
initialize collections we should be consistent in that usage. If we want to
provide a factory that likes a rest parameter then it should be
Set.from(...values)
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss