January 19 meeting notes

Brendan Eich brendan at mozilla.org
Thu Jan 19 21:09:46 PST 2012

> Axel Rauschmayer <mailto:axel at rauschma.de>
> January 19, 2012 8:20 PM
> Given that this desugaring will only kick in if a closure leaves the 
> loop (right?), this is a case of automatically doing the right thing 
> (and only if it’s warranted).

Right, it's not observable without a closure.

The downside, if it is a downside, is that if you take a literal C/C++ 
point of view, and change

let a = [];
for (let i = 0; i < 10; i++) {
a.push(function () { return i; });
for (let j in a) {
assert(a[j]() === j);


let a = [];
let i = 0;
for (; i < 10; i++) {
a.push(function () { return i; });

then the assert-loop will have to change:

for (let j in a) {
assert(a[j]() === 10);

but that's what you asked for. for(let ...;;) is a special form.

> -- 
> Dr. Axel Rauschmayer
> axel at rauschma.de <mailto:axel at rauschma.de>
> home: rauschma.de <http://rauschma.de>
> twitter: twitter.com/rauschma <http://twitter.com/rauschma>
> blog: 2ality.com <http://2ality.com>
> Brendan Eich <mailto:brendan at mozilla.org>
> January 19, 2012 8:02 PM
> Yes kids, this means we are going with MarkM's lambda desugaring from:
> https://mail.mozilla.org/pipermail/es-discuss/2008-October/007819.html
> So any closures formed in the body of such a for(let...;...;...) loop 
> will capture the binding created afresh for that iteration. This 
> avoids the nasty need for CoffeeScript "do" or the expanded JS 
> equivalent of an IIFE surrounding the closure to create per-iteration 
> storage for a copy of the loop control variable.
> Contrary to Jon Zeppieri's good argument at
> https://mail.mozilla.org/pipermail/es-discuss/2008-October/007826.html
> that
> {
> let x = 0;
> for (; x< n; x++) ...
> }
> should have different behavior than
> for (let x = 0; x< n; x++) ...
> those of us left from the TC39 meeting (missing a few reps, short of 
> quorum) favored the greater-good argument ofprogrammer who follow'let 
> is the new var' and who form closures in loops benefiting from the 
> fresh let binding being captured, instead of one binding per loop 
> where the likely value of the binding is the terminating loop control.
> Yay (I'm pretty sure).
> /be
> Waldemar Horwat <mailto:waldemar at google.com>
> January 19, 2012 4:40 PM
> Second day meeting notes.
> Revisited octal/binary constants.
> Waldemar: Note that we currenty allow both upper and lower cases for 
> a, b, c, d, e, f in hex literals as well as e in exponents and x in 
> hex literals. Breaking symmetry by forbidding upper case for b and o 
> to avoid lookalikes would be "nanny language design". We can't forbid 
> lookalikes anyway:
> {
> let y = 3;
> {
> let у = 7;
> return y;
> }
> }
> This is a valid ES6 strict function body that returns 3, of course. 
> The second let defines a local variable named with a Cyrillic letter.
> Decision: Allow upper case B and O to start binary or octal literals.
> Complex discussion about what's feasible in static checking of 
> references from modules. Discussed issues with integrating script code 
> eval'd from cross-origin XHR requests and the (anti-)merits of using 
> var to declare globals.
> MarkM: Abandon static checking.
> Waldemar: MarkM's example from yesterday is an important use case: 
> using a typeof check to see if a variable is defined and later in the 
> same module conditionally dynamically defining it if it wasn't and, 
> even further down in the module, using it. A static check would flag 
> the uses and prevent the module from loading.
> Allen: This is a good use case for pragmas.
> MarkM, Waldemar: Example of a successful strict transition: Nowadays 
> the two of us don't even know non-strict Perl because it's too weird. 
> We learned the cleaner strict version, always set the pragma, and stay 
> within the strict version. Anything non-strict is considered to be 
> broken until it can be upgraded to strict.
> Philosophical discussion about modality, whether a "mode" should be 
> called a "dialect", etc.
> Summary of static checking pain points that need resolutions:
> - Out-of-order asynchronously loaded scripts
> - Concatenation of scripts
> - Dynamic testing for variable existence and conditional use if it exists
> Resolution: Will do more work and come back to this area.
> Allen: Do top-level let and const create properties of the global object?
> DaveH (channeling Andreas): No, but functions do.
> Sam: If they don't then the T-shirt Erik is currently wearing wouldn't 
> work.
> Many agreed that we can't break the T-shirt.
> DaveH: What if there are duplicate top-level bindings?
> MarkM: Top-level let should behave as much as possible the same as 
> concatenated scripts.
> Waldemar: What about read-eval-print loops?
> MarkM: Each eval inserts one more nested scope.
> Waldemar: What if someone does this:
> > let x = 3;
> > function foo() {return x;}
> > let x = 7;
> This would leave foo returning 3.
> MarkM: That's the proper behavior. Anything else has problems.
> Waldemar: [incredulous]
> Allen: We shouldn't spec read-eval-print loops.
> DaveH's summary of issues:
> - Can we get to a world where var is completely unnecessary?
> - Can we do the above for all important top-level patterns?
> - Can we do the above without ever needing nonstrict mode?
> - Should let have consistent semantics in all contexts?
> Consensus on:
> - Should multiple scripts or scripts and attributes share lexical 
> scopes other than via global objects? No.
> - Consensus that concatenating multiple scripts via scope nesting 
> semantics is undesirable.
> Sam: What about global scope polluters?
> let Object = 7;
> should be an error. But implementations have other sources of 
> polluters (such as predefined implementation features or other HTML 
> elements on the page) that can cause global clashes.
> Allen: Top-level declaration overriding is allowed if the existing 
> property has the attributes writable:true and enumerable:true (and the 
> new declaration stays enumerable). Configurable doesn't (sic) enter 
> the decision.
> Allen: See https://bugs.ecmascript.org/show_bug.cgi?id=78
> DOMs now declare properties on the prototype of the Window object.
> Internationalization report
> Discussion about a name (and domain name) for the internationalization 
> test suite. 402 is the current next unused ECMA standard number. We 
> probably shouldn't wait for two more ECMA standards to be 
> published.... Mild consensus on putting the test suite in a 
> subdirectory of test262.
> Discussion about whether to keep internationalization as a separate 
> document or to merge it into ECMA-262. Current decision is to keep it 
> separate for faster evolution of both standards and to avoid 
> bureaucracy with ISO.
> Discussion about the choice of name for the global variable via which 
> the internationalization API is accessed. Possibilities are 
> Globalization and Intl. Need to look for web breakage these would cause.
> Everybody needs to review internationalization spec before the vote in 
> March.
> Debate over whether to use TypeError or RangeError for domain errors.
> DaveH: Use TypeError
> Allen, Waldemar: Use RangeError. Note that RangeError is used for more 
> than just numeric intervals -- passing 3.5 to a function that expects 
> an integer in [0, 2^32) throws a RangeError in ES5.1.
> Test262 status report: No invalid test cases left.
> MarkM: Want some means to avoid having test262 penalize 
> implementations that anticipate incompatible breaks that have been 
> approved by the committee (possible example: completion reform in ES6).
> Allen: Distinguish between spec bugs and breaking spec revisions.
> DaveH, Sam: In reality the test suite provides political pressure. 
> Want to avoid applying that pressure for features that we decided to 
> break in the future spec.
> Alex: Create a category of deprecated tests that, just like the 
> nonnormative ones, run but don't factor into the score.
> DavidF (in response to discussion assertions about test262 always 
> tracking only the latest ECMAScript version): Microsoft wants to 
> retain an ES5.1 variant of test262 even after ES6 is released.
> Consensus: Create a third category of tests for features that are "no 
> longer endorsed".
> Mozilla hasn't signed a contributor agreement yet. Waiting for having 
> something to contribute.
> Istvan's report about the chaos that Intel caused at the last GA 
> meeting and the developments since then.
> Allen: We should formalize the RANDZ for TC39.
> Intel will be here for the next meeting of TC39.
> TC45 also had an understanding that their contributions would be RANDZ.
> MarkM: If we can't formalize RANDZ in TC39 somehow, several members 
> will desire to take the standards activity to an organization that can.
> Varied and long discussion about IPR policy developments.
> ECMAScript® got registered as a trademark in Switzerland.
> At next meeting MarkM will present a tiny API proposal for maps and sets.
> Allen: Reset agenda for next meeting. Don't include zombie carryovers.
> Brendan: Gavin is working on classes.
> ArrayTypes:
> var Int8Array = new ArrayType(Int8);
> var arr1 = new Int8Array(100);
> var arr2 = new Int8Array(256);
> var MyStruct = new StructType({extra: Int8Array(100)});
> Note that Int8Array does different things when called with or without 
> new. Debated how to do this -- specialize on new (can be done via 
> proxies) or on whether the "this" value is undefined or not.
> Allen, DaveH: Classes should support the ability to express APIs such 
> as this one.
> Waldemar: How would this work?
> let t = Int8Array(100);
> var arr3 = new t;
> Luke: It wouldn't.
> Some debate ensues.
> DaveH: There should be two kinds of array type objects: sized and 
> unsized. Calling an unsized one as a function with a length argument 
> returns a sized array type object. Can call new on the resulting sized 
> array type to obtain an array instance. Luke now agrees.
> Can construct an array value as a view over part of an ArrayBuffer.
> Waldemar: This brings up endian issues.
> Luke: Array buffer is exposed only if you allocate an array using an 
> explicit ArrayBuffer. The forms that create arrays without explicit 
> ArrayBuffers don't expose endianness.
> DaveH: The endianness ship has sailed with TypedArrays. It's 
> implementation defined.
> DaveH: People use this to aid with file I/O.
> Waldemar: The two statements above contradict each other. All 
> implementations will want to make the same choice to avoid 
> nondeterministic behavior, particularly if people use it for file I/O. 
> We should pick the main one and mandate it.
> Brendan: It's already specified as little endian for arrays and big 
> endian for data view.
> Sam: Looked at the Kronos spec and it doesn't say anything about 
> non-data-view endianness. It's not specified.
> DaveH: We should try to spec endianness if possible.
> Debate over whether the following should be an error in strict mode 
> (or "extended mode" if there is such a thing). It isn't an error in 
> ES5.1 strict.
> function (e) {var e;}
> Consensus: No, we should not change strict mode incompatibly like 
> this. This is valid in all modes.
> Brendan: It should be an early error to have a var hoist across a 
> catch-block with the same variable name.
> Also, "function (e) {let e;}" should always be an error.
> Allen, Sam: Module mode will be the same as strict mode, except 
> possibly for additional free variable static checks.
> Discussed Allen's list of current ES6 extended mode breaking changes 
> from the "ES6 opt-in, reloaded" thread.
> Consensus: For each of these, either we introduce it in all code 
> (maybe all strict code) or we don't do it.
> Discussion about scope of for-bindings.
> for (var x = ...;;) {...} will, of course, retain ES1 semantics.
> for (let x = ...;;) {...}
> Allen: This will behave as in C++: x is bound once in a new scope 
> immediately surrounding just the for statement.
> DaveH: Strangely enough, this creates a new x binding in Dart at each 
> iteration.
> There's an alternative semantics that creates an iteration-local 
> second x inside the loop and copies it back and forth. Debate about 
> whether to go to such complexity. Many of us are on the fence.
> Waldemar: What happens in the forwarding semantics if you capture the 
> x inside a lambda in any of the three expressions in the head?
> If this happens in the initializer:
> DaveH's option: The lambda would capture an outer x.
> Alternative: The lambda captures a hidden second x.
> Waldemar's option: The lambda would capture the x from the first 
> iteration. The let variable x is bound once through each iteration, 
> just before the test, if
> for (let x = expr1; expr2;) {...}
> were:
> while (true) {
> let x = first_iteration ? expr1 : value_of_x_from_previous_iteration;
> if (!expr2)
> break;
> ...
> }
> MarkM: Just discovered that his desugaring has the same semantics as 
> Waldemar's option.
> for (const x = ...;;) {...} behaves analogously to let, whatever we 
> decide let will do.
> Those opposed earlier to new-binding-per-iteration hop back onto the 
> fence. Waldemar, Brendan, and DaveH hop off the fence to now support 
> it, as it will cure an annoying gotcha in practice. Looks like we have 
> support for it now.
> End of meeting.
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

More information about the es-discuss mailing list