Ecma/TC39 Meeting – Jan 29 2013

link January 29 2013 Meeting Notes

John Neumann (JN), Norbert Lindenberg (NL), Allen Wirfs-Brock (AWB), Rick Waldron (RW), Waldemar Horwat (WH), Tim Disney (TD), Eric Ferraiuolo (EF), Sam Tobin-Hochstadt (STH), Erik Arvidsson (EA), Brian Terlson (BT), Luke Hoban (LH), Matt Sweeney (MS), Doug Crockford (DC), Yehuda Katz (YK), Nebojša Ćirić (NC), Brendan Eich (BE)

JN: ...Welcome and introduction, agenda. Discussion of TG/TC procedural changes. Please review and feedback.

...Adoption of the Agenda.

WH: All of the initial agenda items are missing references. Can't figure out what some of them are referring to from just their titles. WH, JN: Please put proposal links (or other references) into agenda items like we did in the past.

AWB: Are there items that need to be discussed that aren't yet on the agenda?

STH: Will provide an update on Modules

link Added: 4.14 Modules Update

AWB: Discussion about Proxy?

STH: A lot of discussion about the interaction of Proxy and Private Names

...Should we wait for Mark Miller?

AWB: Nowhere near consensus on any point of discussion from the mailing list.

link Added: 4.15 Proxy Issues

LH: (to AWB) did you want to give an update on the spec?

link Added: 4.16 Spec Status Update

JN: We should have a discussion regarding the list of items that will actually end up in ES6 and determine exact ES6 additions.

RW: Let's set this as an agenda item for the next meeting and try to reduce the number of submitted agenda items. This allows everyone the opportunity to prepare for the large scale discussion.

JN: Will add an agenda item for March.

...Brief discussion about features that may or may not be ready; STH identifies: event loop (dependency of modules, Object.observe)

AWB: Two issues: Semantic completeness of the designs and what does it take to implement these into the language.

WH: Are proxies ready? AWB: Not yet.

Mixed discussion.

JN summarizes as part of 4.16 discussion

link Agenda Approved

link November 2012 Minutes Approved

link 4.16 Spec Status Update

(Presented by Allen Wirfs-Brock)

AWB: Revisits Nov 22, http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

Discussion re: instanceof.

EA: Checks and changes to implementations that use instanceof

STH: Expect slow down from use of instanceof?

AWB/EA: yes.

WH: Concerns, how do you tell if a regex is a regex

YH: Not with instanceof, use Object.prototype.toString

AWB: Shouldn't use instanceof

EA: This hook makes instanceof behave they way you expect it.

AWB: Revisits Dec 21, 2012 Draft changes

Mixed discussion re: keeping up to date with the spec drafts, request for more technical-focused reviews.

link __proto__.

LH: Begins with raised points about __proto__...

Mixed discussion about __proto__ semantics.

AWB: There is an underlying feeling that we don't like this and we need to get over that.

LH/YK: Agree.

DC, WH: Disagree.

YK, DC: Discussion about __proto__ reality.

YK: We need consistency.

DC: We should not standardize and leave as is.

Impasse.

LH: Similar issues with block scoped function declaration incompatibilities.

WH: We should give up on __proto__ in the same way that we gave up on "with"

EA: IE is implementing for web compatibility

AWB: The defacto standard for mobile web uses __proto__

EA: IF we could go back, we would do it differently

YK: We just need compatibility

LH: We need to just suck it up and standardize

Mixed discussion re: user code and __proto__

AWB: (clarifies) Luke is requesting that we pin down the __proto__ details as soon as possible.

WH/DC: (have concerns, against standardizing __proto__)

YK/BE: Discussion re: interop with current implementations.

BE: (Review of latest changes to __proto__ in Firefox)

EA: Matches Safari

BE: __proto__ is configurable (can be deleted), accessor (getter and setter throw), reflection does not leak.

AWB: Involves magic

BE: Yes, but minimal. (Confirms that latest __proto__ is out in wild, Firefox)

WH: Clarify "poisoning"?

BE: When you call it, it throws.

WH: So how does it know when not to throw? (If it always throws then it won't work.)

EA: Throws if called with object and setter coming from different realms

...Discussion re: MOP semantics with __proto__

BE: Proxy has to stratify the MOP.

AWB: Another issue... Objects that are non-extensible, can you change __proto__? Specifically, now that we're talking about being able to change __proto__, what type of objects can be changed?

BE: Wait for Mark?

YK?: Changing __proto__ is a write, not adding a property, so it should not be affected by extensibility.

AWB: Agree.

Hold until Mark Miller is present.

EA: ES5 requires [[Prototype]] to be read only when the object is non extensible.?

(Further discussion)

BE: Let's get back to this with Mark present and come to a conclusion.

link 4.1 is/isnt operators

(Presented by Allen Wirfs-Brock) http://wiki.ecmascript.org/doku.php?id=harmony:egal

AWB: The plan of record on the wiki is that there is an "is" and "isnt" operator. There are various discussions on the mailing list that refer to this, but also to Object.is and Object.isnt. We need a final decision on the operator form.

YK: The discussion was to move the world from ==?

YK: The differences between === and is are significantly small.

BE: On behalf of Dave Herman and Jason Orendorff... Syntax needs to be worth the expense and there options.

General agreement.

WH: (question about new type NaNs)

AWB: No spec provisions, currently...

WH: Hypothetical discussion about new "decimal" type with a "decimal NaN" and the implications of NaN equality. The issue that would arise would be that a decimal NaN would be unequal to itself but would be distinguishable from the regular Number NaN. Therefore the example code for how users could implement is wouldn't work. However, if is is a language feature, then an implentation can fix it up to behave correctly when it adds additional primitive types such as Decimal, just as it would fix up the behavior of ==, etc.

link Conclusion/Resolution

Consensus on No operator

Do we want API? Yes.

What is the name? Object.is(x, y) (NOT Object.isnt, ! is sufficient for negation)

If it's "all discriminating", should it discriminate +0/-0? Yes

NaN is not different from NaN (all NaNs are equated).

Every observable value "is" itself and nothing else.

link 4.4 Is there are need for Number.isNaN if we have Object.is available?

BE: Keep the concerns separate.

AWB: If we have Object.is, we don't actually need Number.isNaN

DC: Object.is is sufficient.

BE: (Whiteboard example)

RW: Punt on Number.isNaN for ES6, defer to ES7 hinging on need based on potential emergent library code.

WH: Number.isNaN is analogous to other Number functions such as Number.isFinite and Number.isInteger. It should stay.

(toInteger was mistakenly changed to toInt, discussion leads to revisiting March 29th 2012 notes where no rationale was recorded. https://mail.mozilla.org/pipermail/es-discuss/2012-March/021919.html)

Given the existence of the other Number.is* functions, several people flip their views.

link Conclusion/Resolution

Overturn the Number.toInteger=>toInt change. Restore as toInteger. (Brendan, can you fill in the rationale for this?)

Number.isNaN remains in ES6

link 4.2 SameValue for Map/Set equivalence?

link 4.3 Parameterize the equivalence operator for Map/Set?

AWB: For ES6, only specify a limited set of comparison operators?

Discussion re: arbitrary comparisons?

Hash Codes?

STH, WH, several others: Need to support strict (is) equality at a minimum.

YK: If the goal is to avoid whole new design issues, stick to strict equality.

BE: Reminder that adding hash codes now is too late in the game.

YK/AWB: Concerns that maps with strict equality will trip people up.

YK: Typically, Maps have custom equality capabilities.

AWB: (Reminder of hash code pitfalls) But only strict equality will be a disaster, but can't introduce hash codes at this stage.

AWB: [if we support both strict and other kinds of equality] suggest the default: +0/-0 are the same; NaN is a value, that is equal to itself for Map/Set equivalence.

Assuming we have a mechanism to override...

Ideally, we'd want to set this in the constructor, but there is already a single optional initializer argument.

BE: Let's find a champion to work this out over the next two days.

AWB: I can do this.

link Conclusion/Resolution

To revisit, pending proposal from AWB. (See Jan 31 notes)

Must address the minimal requirements on the wiki

link 6 Second Edition of ECMA-402 (Internationalization)

Last Update: https://github.com/rwldrn/tc39-notes/blob/master/es6/2012-11/nov-27.md#internationalization-update

NC: Approved to continue work. APIs covered, people assigned to write strawman. Have API changes to be written into the spec, based on use cases that have emerged.

NL: Normalization in the language specification: talked about 2 additional normalization forms.

  1. CF, Case folding
  2. NFKC_CF, Normalization form, Compatibility Decomposition, followed by Canonical Composition, combined with case folding

NL: Chrome 24 shipped with the first implementation of Edition 1, not prefixed any longer

NC: Overrode the old methods String.prototype.localeCompare, Date/Number.prototype.toLocaleString

BE: Good so far?

NC: Have some bugs with performance, but can address.

EA: No issues with actual semantics?

NC: No complaints.

JN: Schedule? On track?

NC/NL: So far, but rely on ES6.

Discussion about overlapping schedule. Current plan for Intl 2 is for approval in June 2014, but ES6 may slip to the same date. NL wondering whether TC 39 can review two specs at the same time; AWB thinks that should be OK.

Notes from NL/NC:

December 12: Ecma GA approves ECMA-402 http://ecma-international.org/publications/standards/Ecma-402.htm

January 10: Google shipped first implementation without prefix in Chrome 24

December 14: Internationalization ad-hoc met

  • discussed scope in more detail, assigned strawman writing

Since then: Strawmen written, but not reviewed yet:

Strawmen assigned, but not written yet:

  • character properties (regex or API?)
  • display names
  • time duration formatting
  • alphabetic index

API changes to be written up:

  • normalization (language spec - add CF and NFKC_CF)
  • case conversion
  • time zone support
  • script reordering in Collator
  • pseudo-numbering systems in NumberFormat

link 4.5 Why standardizing on __proto__ and not __define(G|S)etter__, __lookup(G|S)etter__?

(Based on a recent es-discuss thread)

Why __proto__ normative mandatory in ES6 but no __define/lookup... is:

  1. __proto__ much more used on the mobile (iOS WebKit-first) web, no equivalent interop pressure for __d/l.
  2. ES5 is in all new/evergreen browsers and it has standard APIs supplanting __d/l but nothing for writing to __proto__.

Therefore __proto__ gets standardized, __d/l do not.

Rationale for not adding Object.setPrototypeOf https://mail.mozilla.org/pipermail/es-discuss/2012-May/022904.html

link Conclusion/Resolution

Consensus that __define(G|S)etter__, __lookup(G|S)etter__ will not be standardized, nor added to an Appendix.

link 4.8 Refactored new operator and the @@create method

(Presented by Allen Wirfs-Brock)

Slides (pdf): http://wiki.ecmascript.org/lib/exe/fetch.php?id=meetings%3Ameeting_jan_29_2013&cache=cache&media=meetings:subclassing_builtins.pdf

The Basic Issue:

  • Object Allocation and object initialization are separable issues.
  • Subclassable abstractions require program level control...

Why Doesn't this work?

1
2
3
4
5
6
7
8
9
10
11
12
13
class Vector extends Array {
constructor(...args) {
super(...args);
}
}
let a = new Array();
let v = new Vector();
a[5] = v[5] = 5;
a.length; // 6
v.length; // 0

Because...

  • Array uses a special exotic object representation that changes the semancs of [[DefineOwnProperty]].

  • The object that new Vector creates and passes to the Vector constructor is an ordinary object, not an exotic Array object.

  • Even with the super call, the Array constructor doesn’t transform its this object into an exotic Array

First Solution

  • Use normal [[Construct]] for built-­‐ins.
    • Move magic ini1aliza1on (internal data proper1es and internal methods) into the constructor func1on, post object alloca1on.
  • Internal data proper1es need to be expandos (probably based upon private symbols)
  • Built-­‐in methods use internal data property sniffing instead of [[Class]] brand check.

Objections

Ollie's Objections:

  • Doesn't want internal data properties to be expandos
  • Implementors want to allocate different machine/C level data structures for different kinds of built-ins.

Allen's Objections:

  • What about internal method conflicts?

WH: Jason's Objections:

  • More than one magic constructor can be applied to an object
1
2
3
4
5
let d = new Date();
Map.call(d);
console.log(d.getYear()); // 2013
Map.prototype.set.call(d,”month”, “January”);
console.log(Map.prototype.get.call(d,”Month”)) // January

What do other dynamic OO languages do?

  • Separate object allocation and initialization into separate phases.
  • The "shape" and special characteristics of an object are fixed during the object allocation phase. – Kind of like what [[Construct]] does, but...
  • The allocation phase is defined as a separate class method – Can be inherited, or over-ridden, or super-invoked by subclasses.

Sounds Good, Let’s see if it works for JavaScript

  • @@create is a well known symbol that when used as a property of a constructor provides the alloca1on method for that constructor.
  • New definition of the ordinary [[Construct]] :
    1. Let creator be [[Get]] of this constructors @@create property
    2. If creator is not undefined, then a. Let obj be the result of calling creator with this constructor as its this value.
    3. Else, fallback implementation a. Let obj be a new ordinary object with its [[Prototype]] initialized from this constructor's “prototype” property.
    4. Call this constructor with obj as the this value and the original argument list.
    5. Return obj.

BE, EA, YK, WH, others: Get rid of the fallback implementation and just throw if there is no @@create. It's unnecessary complexity.

  • Most constructors just inherit Function.prototype[@@create] which allocates a new ordinary object with its [[Prototype]] initialized from this.prototype (the constructor’s “prototype” property).
  • new Foo() <=> Foo.call(Foo[@@create]())

TODO: Copy slide text to notes?

Discussion re: class Foo extends ?? semantics discussed in July, https://github.com/rwldrn/tc39-notes/blob/master/es6/2012-07/july-26.md#maxmin-class-semantics

WH: What happens when you do Number[@@create]?

AWB/EA: Creates a new wrapped Number object.

BE: new Number() <=> Number.call(Number[@@create]())

AWB: Built-in @@create methods are non-writable, non-configurable. Just like built-in "prototype" properties (From slides).

... Back to slides.

@@create Also Useful for Application Classes

  • DIY Branding
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import $$create ...;
const $fooBrand = Symbol(true); // or use a WeakMap
export class Foo {
isFoo() {
return !!this[$fooBrand];
}
}
Object.mixin( Foo, {
[$$create]() {
let obj = super();
Object.defineProperty( obj, $fooBrand, {
value: true
});
return obj;
}
});

(note: $$ sigil for illustration purpose only)

WK: The @@create could be hijacked and used to brand some other object with my object's brand.

AWB: No different from hijacking from an Array or Date...

WK: Good for branding case, not for security

AWB: (Gives example of how you might make it work). Explanation of creating Proxy based instances with @@create (see slides)

ES5 Built-In Branding

Consider ES5+ Reality:

1
2
3
4
5
6
7
8
9
10
11
12
function T() {
var obj = [];
obj.`__proto__` = T.prototype;
return obj;
};
var t = new T();
t[5] = 5;
t.length; // 6
Array.isArray(t); // true
t.toString(); // [object Array]

Built-in branding is based on the shape and capabilities of the actual instance object.

ES6: @@create Determines Branding

  • Array.isArray will report true for subclass instances that are built-in exotic Array objects. These are allocated using Array[@@create];
1
2
let v = new class extends Array {};
Array.isArray(v); // true
  • Unless over-ridden using the @@toStringTag, {}.toString will report the legacy [[Class]] for built-in subclass instances if they are allocated using a built-in @@create method.

WH: If you're call isArray and it returns true, you'd expect to call Array.prototype methods.

AWB: No guarantees about the prototype chain

MM: Even if Array is frozen, the Array.prototype is mutable and I can add my own malicious push, pop, join.

MM, AWB, WH: (Discussion of security concerns)

Agreement that none of this weakens any existing invariants.

No Need for [[Class]] or [[BuiltinBrand]]

  • These are really just specification devices for talking about specific forms of objects.
  • Spec has always also used language like "an Array object" or "a RegExp instance"
  • In ES6 spec. all [[Class]] uses uses can replaced with language like: - "is an exotic array object" <=> [[Class]]=="Array" - "has a [[Match]] internal data property" <=> [[Class]]=="RegExp"

File: [[Match]] => [[RegExpMatch]]

Testing the |this| value almost works

(See slides for code example)

link Conclusion/Resolution

Consensus on @@create, allocation and initialization decoupling.

Constructors need to be able to recognize initialized instances

  • Built-ins can do this via existing internal properties
  • User code could roll its own

Probably better to formalize initialized state as part of ES object model

  • Add one bit of state to every object: initialized/unitialized.
  • Built-in @@create methods set new object state to uninitialized.
  • Object.call(uninitObj) and other built-in constructors set initialized this objects to initialized state.
  • Object.isInitialized(obj) is a new method that only returns false if obj is an object that is in the initialized state.
  • Object.create(), {}, [] and various built-in functions create objects that are already initialized (backwards compat)

Semantics...

1
2
3
4
5
6
7
8
// Decoupling allocation and initialization:
// Calling new X()...
class X { // 1. X[@@create](), allocation
constructor() { // 2. Initialization
super();
this.state = "ready";
}
}

EA: Worth the additional bit? Is the need common enough to address with new language API surface?

What about @call?

MM: @construct? If one is specified, otherwise ... super call vs. super construct (Mark—Sorry, I had trouble following this—can you fill this in? Thanks!)

MM: Are there any objections to the parallel @construct entry point.

YK: It makes less sense in the ES6 context, since classes are focused around defining a constructor...

MM: I see, then call is the odd-ball. Agree with the objection.

YK: @call makes sense in the class case, @construct makes sense in the function case.

AWB/YK: Need statics to make the @call

Mixed discussion regarding "static"

Yehuda will draft a static strawman for tomorrow.

(Break)

YK: All functions have a call and construct property, I propose to expose them

AWB: All functions are constructible, when a function is "newer", something happens before the function is invoked.

AWB/YK: (Discussion re: existing semantics of function call and construct)

BE: The idea of having state in objects for initialization...

WH: The main point of the discussion was that many are uncomfortable with adding an extra bit of state to objects to define whether they're initialized or not and, worse, that state is not a reliable indicator of whether a function was called via Foo() or new Foo(). Someone could forget to set the initialized bit (in a variety of ways) and disrupt further code at a low level. The consensus seemed to be to get rid of that state and instead use either separate call and construct code or some way to detect whether code was called as a function or as a constructor, although we hadn't decided on the details

[STH: conclusion/resolution: no new bit of state (IOW, I agree with WH)]

Various Oddities/Backward Compat Issues, 1

...Missed first slide...

Various Oddities/Backward Compat Issues, 2

  • Array.prototype.concat
    • Currently always creates Array instance, for subclasses usually want subclass instance
      • Change to use subclass constructor to create subclass instances but only when this object is tagged as array subclass
    • Currently auto-spreads Array instance arguments
      • Similar to above, auto-spread tagged array subclass args.
  • Must compatibly support this idiom:
    • [].concat.apply(Array.prototype, arguments);
  • Precomputing result length will support use with TypedArrays
  • Similar result object handling for slice, splice, map, filter(?)

(Re: Bullet 1) WH: Concerned about the proliferation of "types of an object"... class, prototype, type... species?

(Re: Bullet 2) Discussion focuses around built-ins whose prototype property are first-born instances of that object, eg. Array.prototype is an Array. The desire was to remove this from ES6, however there a slew of issues that are not specifically edge cases rise to the surface.

Conclusion/Resolution, Bullet 2

Brendan to experiment with changing the prototype properties of Boolean, Number and String away from first born instances into ordinary object ([object Object]).

(Re: Bullet 4) Discussion focuses on what type ("species") of object should be created by these methods when subclassing.

AWB: All of them, "species" is what you want, except in the case of map. For slice, splice and filter, you always want to operate on and return the "species" calling.

?: Want to customize it differently for different methods.

WH: (Doesn't want another "type" thing)

YK: (Doesn't think it's a problem)

AWB: You can always cast your object back into the type of your class with this.constructor.

Illustrating Bullet 4:

1
2
3
4
5
6
7
8
9
10
class V extends Array {
constructor(...args) {
super(...args);
}
}
var v, m;
v = new V(1,2,3, );
m = v.map(val => val * 2);
console.log( m instanceof V ); // false :(

Various Oddities/Backward Compat Issues, 3

  • String.prototype.match, replace, search, split.
    • Currently spec'ed to directly use RegExp internal APIs which limit the ability to use them with RegExp subclasses that use alternative engines that don't expose those APIs
    • Refactor into public operations upon RegExp subclass
    • String methods delegate to RegExp methods

MM: Confirm that any symbols defined only need to be unique, not private?

AWB: Yes.

link 4.10 Data collection/analysis: Function-in-block, duplicate parameter names, const, strict mode, var let/let[x]=1, and maybe more

(Presented by Brian Terlson)

Slides (pdf): http://wiki.ecmascript.org/lib/exe/fetch.php?id=meetings%3Ameeting_jan_29_2013&cache=cache&media=meetings:real-world-js-code.pdf

1.85% of scripts make use of function hoisting intersection semantics. Almost all of these are due to functions defined inside arms of an if statement. Few examples of defining functions inside loops. No scripts do let[x]. 10% of "use strict" directives are incorrect because they're not in the prologues.

Mixed discussion regarding the actual expectation of these cases.

Can the tests be expanded beyond the top 10k?

BE: w/r to FIB, should we go with strict mode standardization?

YK: Does it always leak the identifier?

MM: In different ways.

Discussion regarding language forking.

LH: (Identifies a dark future that hinges on "use strict")

MM: That should be the future.

... YK: Are there intersections of existing implementations that can be spec'ed?

Mixed discussion.

Table discussion until tomorrow.

Ecma/TC39 Meeting – Nov 29 2012

link November 29 2012 Meeting Notes

John Neumann (JN), Allen Wirfs-Brock (AWB), Waldemar Horwat (WH), Brian Terlson (BT), Luke Hoban (LH), Rick Waldron (RW), Eric Ferraiuolo (EF), Doug Crockford (DC), Yehuda Katz (YK), Erik Arvidsson (EA), Mark Miller (MM), Dave Herman (DH), Sam Tobin-Hochstadt (STH), Istvan Sebastian (IS), Andreas Rossberg (ARB), Brendan Eich (BE), Alex Russel (AR), Matt Sweeney (MS)

link Approval of ECMA/TC39 Scope Declaration

(Presented by John Neumann)

JN: (presents scope document for approval)

link Conclusion/Resolution

Approved.

link Scoping for default arguments revisited

(Presented by Allen Wirfs-Brock) See Slides

AWB: (Review legacy requirements)

Two Params, Same Name allowed (non-strict)

1
2
function f(x,x) { console.log(x); }
f(1,2); // logs: 2

Parameter and a Var with Same name

1
2
3
4
5
function g(x) {
var x;
console.log(x);
}
g(1); // logs: 1

Function Declarations Override Parameter Bindings

1
2
3
4
5
function h(x) {
function x() {return 2;}
console.log(x());
}
h(function() { return 1; }); // logs: 2

link Proposal Part 1

  • Simple ES<=5.1 parameter lists introduce "var bindings" in the top level scope of a function
  • All ES<=5.1 rules apply
    • Duplicated parameter names
    • Parameter names may be same as var or function Declaration
    • (missed) see slides...

ARB: These are simply the requirements.

link Proposal Part 2

  • If a parameter list uses ANY parameter syntax introduced in ES6, new rules apply:
    • Destructuring Parameters
    • Default value initializers
    • Rest Parameters
  • New Rules:
    • Parameter lists introduce "let bindings" in the top level scope of the function
      • No duplicate param names
      • Parameter names may not be the same as any other function top-level
    • TDZ rules apply to parameter default value initializers
      • Hoisted top-level function/var declaration are initialized after parameter initialization
    • "strict" arguments object (copy of actual args, no parameter joining)

DH/YK/LH: This is problematic for extant offending code, that is updated to use ES6 syntax. One syntax change shouldn't have adverse effects on other, not directly related, syntax.

RW: If offending code exists, it would be smart to fix the issues, new syntax does new things.

YK: Sympathetic, but disagrees

New Rules Examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function f(x, x, ...rest) {}
Syntax Error: duplicate parameter name (Rule 1.A)
function f(x, {a:x, b:y}) {}
Syntax Error: duplicate parameter name (Rule 1.A)
function f([x]) { let x; }
Syntax Error: redeclaration of parameter x (Rule 1.B)
function f([x]) { var x; }
Syntax Error: redeclaration of parameter x (Rule 1.B)
function f([x]) { {var x;} }
Syntax Error: redeclaration of parameter x using hoisted var (Rule 1.B)
function f([x]) { {let x;} }
Valid, redeclaration is in inner block
function f([x]) { function x(){} }
Syntax Error: redeclaration of parameter x (Rule 1.B)
function f([x]) { class x {} }
Syntax Error: redeclaration of parameter x (Rule 1.B)

WH/AWB/ARB: discussion about parenthesis on parameters

ARB: Points out that this is why 1JS becomes a problem where we introduce micro-modes to make things work

AWB: We need to have these to make these things work correctly

MM: Also nervous about these micro-modes, but want to see the rest of the proposal

New Rules Examples, Cont...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function f(x, y=x) {}
Valid, x has been initialized when y's default value expression is evaluated.
function f(x=y, y) {}
Runtime: ReferenceError exception y not initialized (Rule 2)
const a = "A";
function f(x=a) {}
Valid
function f(x=a) { var a;}
Runtime: ReferenceError a not yet initialized (Rule 2.A)
function f(x=a) { const a = "A";}
Runtime: ReferenceError a not yet initialized (Rule 2.A)
function a() {return "A";}
function f(x=a()) {}
Valid, a is initialized in surrounding scope, at time of parameter default value initialization.
function f(x=a()) { function a() { return "A"; } }
Runtime: ReferenceError a not yet initialized (Rule 2.A)

MM, WH: I want to preserve:

  1. A Function, as soon as it's in scope is already initialized
  2. A Var variable, as soon as it's in scope is already initialized

ARB: Agree, but these things simply should not be in scope.

DH: We're making mistakes with let all around. We should wait to continue this discussion until this afternoon when all are present.

MM: Luke, where does the let research stand?

LH: Incomplete.

AWB: If there are disagreements with these rules, then someone needs to write rules that cover all these cases.

ARB: I proposed a set of rules and posted to es-discuss. Basic idea: a function with default arguments behaves as if it was a wrapper function supplying the default arguments. So initializers cannot see any definitions from the body.

link Simplest example:

1
// scope boundaries

Ecma/TC39 Meeting – Nov 28 2012

link November 28 2012 Meeting Notes

John Neumann (JN), Norbert Lindenberg (NL), Allen Wirfs-Brock (AWB), Waldemar Horwat (WH), Brian Terlson (BT), Luke Hoban (LH), Rick Waldron (RW), Eric Ferraiuolo (EF), Doug Crockford (DC), Yehuda Katz (YK), Erik Arvidsson (EA), Mark Miller (MM), Dave Herman (DH), Sam Tobin-Hochstadt (STH), Istvan Sebastian (IS), Andreas Rossberg (ARB), Brendan Eich (BE), Alex Russel (AR)

link Syntactic Support for Private Names

BE/LH: Concern that the syntax required too much declaration

LH: Can delve deeper when presenting TypeScript findings. We don't have any experience with the impact of this syntax.

AWB: This is where we left it at the last meeting and I haven't had an opportunity to respond to feedback.

Mixed discussion regarding syntactic pains and impact of @-names

LH: Before it can go forward, someone will need to go back and address the existing issues.

AWB: The concern is the double declaration and we discussed adding a private prefix for method declarations.

YK: Alternatively, module bound private names, where declaration scopes to the module.

Discussion of Kevin Smith's modular @-names proposal...

AWB: The same logic applies to global vs. lexical namespace, and modules.

WH: If you have an @-name somewhere in a module, is it scoped to this module

YK: If you use an @-name it implies binding, and you need to explicitly export

AWB: References an implicit declaration if doesn't already have one?

YK: Yes. (draws example on whiteboard)

1
2
3
4
5
6
7
module "view" {
export class View {
constructor(id) {
this.@id = id;
}
}
}

DH: Points of clarification...

  1. If we're talking about @-names explicitly scope to a module, no declaration nec. Does that make them private or unique?
  • You would have to declare specifically

Reviewing Kevin Smith's gist (https://gist.github.com/3868131) on projector...

ARB: How does this avoid the use of the same name twice?

AWB: You're expected to know your module.

BE: (draw comparison to Go, Dart, CoffeeScript)

DH: The goal is simply to avoid repetitive declaration lists

LH: The notion that declaration of private names as a runtime construct is great, but the syntactic representation needs to be intuitive to "this is a private thing". So far, this feels at odds with those intuitions

DH: Disagrees, this is a static concept and declarations within are intuitively static.

WH/AR/STH: There is no precedence in the language to scope limited binding forms.

DH: Painful if you're required to list out everything

WH/YK: Sharing private names across classes is a problem that needs to be solved.

DH: Implicit scoping is asking for trouble (gives examples)

AWB: Common case where a symbol only needs to scoped to a class, for that case, we have a proposal on the table that covers everything except for fields without a lot of redundant declaration. Beyond the scope of a single class, it seems an explicit declaration at an appropriate level is desirable.

DH: Tied to classes implicitly? But allowed to explicitly bound to other scopes

AWB/DH: Clarification on private for classes.

ARB: Would need to hoist the thing outside the class?

AWB: Only if you're contributing to the thing outside of the class.

BE: If you want an outer scope, put a block around it. ...Kevin's proposal seems to have no support here.

LH/AWB: back to the @-names, we left it at "it's too chatty"

LH: I want syntax for privacy, something less

Discussion about import @iterator in classes...

LH: The immediate problem w/ YK's example on board is that it's unclear that @id... Developers don't want to think about binding names as objects

AWB: (modifies whiteboard)

1
2
3
4
5
6
7
8
module "view" {
private @id; // allows declaring a private name called "id"
export class View {
constructor(id) {
this.@id = id;
}
}
}

Move private @id...

1
2
3
4
5
6
7
8
module "view" {
export class View {
private @id;
constructor(id) {
this.@id = id;
}
}
}

BE: This all may be developer and future hostile.

WH: (agrees)

BE: Developers want declarative form to define an instance field with a private name in one step. We separate those two.

WH: I want to preserve the option of saying one thing

BE: That's what Luke wants.

LH: Most developers don't want to think about declaring their names before use.

AWB: Then we can't address private within a class without addressing field declarations in a class. (moves private @id out of example)

WH: We can't allow this to now be declarable in multiple contexts.

LH: The current behavior of @-names is not what developers expect it to be.

DH: I have contradicting experience. (ie. Racket define-local-member-name)

LH: If you had to do this for every property that you're ever going to use...?

DH: (Agrees with Yehuda's complaints)

BE: Then we need field syntax first.

LH/YK/WH: (nods of agreement)

DH: Let's punt on this for ES6. Too late

EA: How to do @iterator?

DH: We can make that work, but this is too large and too late. There are too many questionable issues w/r to declaration for the sake of scoping a name, without creating a field.

MM: Let's not discount ES7 development.

AWB: I disagree and don't think that we should defer on addressing this.

BE: If we wait and defacto standards emerge, then we're too slow.

MM: Intend to advocate:

  • postpone explicit field declarations to ES7 and things that might conflict until.

BE: Agree

LH: The concern is @iterator?

standard private names and public names

WH: What is the point of contention for the existing field declaration proposal?

BE/AR: (explanation of constructor declaration and hoisting issue)

BE: (whiteboard)

// Mark's proposal from a year ago // http://wiki.ecmascript.org/doku.php?id=harmony:classes

1
2
3
constructor(id) {
private id = id;
}

MM: (reiterates rationale)

LH: (whiteboard) // TypeScript...

1
2
3
4
private id;
constructor(id) {
this.id = id;
}

AWB: What happens when there is foo.id is in the constructor?

DH: So private is to statically reject programs that appear to poke at things that are assumed private?

LH: Confirm

MM: So they foo.id will refer to the same id field?

LH: Yes.

...Unusable for ES6

DH: Proposes... Exactly the semantics as shown, but syntactically only allows field declaration position in classes and import/export.

WH: Important that you will want to declaratively (not imperatively) list fields. Guaranteed to be there in instances of a class. Those who want to lock down the class further might also want extra class attributes that disallow other expando properties, etc. (not the default case, but something you might want to do).

LH: This is now a different discussion. If we introduce a form (re: whiteboard example)...

DH: A future compatible subset of what we discussed before.

Discussion about the baseline problem: Needing two lines to declare a private field.

YK: Not sure why the example that Luke approves of is different from the given syntax.

Discussion of computed object/class-literal properties, rejected due to

  • Runtime duplicate checking
  • Static object literal optimization

LH: Computed properties might be worth revisiting

EA: But you can't predict what the property name will be...

AWB: And you still need to go through the declaration steps...

BE/DH: Revisiting previous consensus on unique name for iterator

DH: No revisit on consideration for string name for iterator

LH: Revisit on square bracket computed properties.

AWB: Square brackets are future hostile... Explanation of the [] Reformation http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation

BE/DH: (volley re: import iterator)

BE: If there is a standard library prelude in ES6 for @iter, that buys time to fully specify for ES7

AWB: Let me summarize... Take the @name proposal without the declaration.

DH: Understand, but the thing we do now needs a coherent story

AWB: Yes, we provide pre-declared @names and that's the end.

LH: Normal lexical bindings?

AWB: No, @name bindings

DH: max/min: only in property name position

WH: Can you stick an @name on any arbitrary object?

AWB: Just getting rid of declaration

BE: max/min

AWB: Existing @names in spec

  • @hasInstance
  • @iterator

DH: the whole benefit of unique names is no name clash

BE: This is why we decided that iterator should be public, because there is no way to avoid existing properties. We want new things to have no clash.

ARB: Want to use it for properties to avoid cross cut

BE: Use for stratified traps.

AWB: Any symbol is fine, doesn't need to private

DH: Why would you decide to expose something as visible...

AWB: There are cases where certain properties might want to be extended or customized.

Discussion of reorganization of Meta Object operations in order to simplify Proxy specification.

WH: The class proposals only permitted private properties on instances of the class. It was never the intent to allow you to create a private instance property @foo of instances of class C and then attach it to random objects unrelated to C.

AWB: At the root, symbols - ie. unique names are a powerful tool

MM: Always in consensus that symbols where a means of assigning and looking up a property by a unique, unforgeable name. It was never specifically tied to classes.

WH: Disagree. That's only one of the privacy proposals. Something got lost in translation in the attempts to merge the two privacy proposals. The class one would let you look up a class-private @foo on any object, but only the class could define an @foo property.

DH/AWB: (Discussion of pre-defined fields on class instances.)

AR: Similar to my constructor pre-amble...

LH: (Summarizing) No clash between the use of symbols at a lower level.

YK: Imagine a map literal...

AWB: Hypothetical Map that used [] for key, might use symbols for keys in that map, now there is an ambiguity at access time.

LH: Care about not having private names becoming lexical scopes

AWB, WH: (in response to question about why @'s are necessary) In the past we've attempted to work through several proposals that don't and it never works

ARB: Concern with meaning of @-syntax being dependent on context: sometimes denotes symbol itself, sometimes value it indexes. Might potentially be ambiguous in some circumstances, e.g. modules

MM: State a proposal:

  • We don't have in ES6: a private or special declaration form.
  • We allow @identifier, that is a symbol let @foo = Unique();
  • After a dot, in property name position, @foo does not refer to a new literal @foo, it refers to the value of the lexically enclosing @foo. We address Andreas's issue with modules separately.

DH: b/c tied to variable declaration forms, no way to know upfront what one of these names is.

AWB: Clarify...

DH: (Re-explains)

AWB: (refutes)

DH: What I was hoping for was declarative syntax closing in... but realize it's totally generative.

ARB/LH: This is a hack

DH: The syntax looks static but is not at all.

MM: Is the hack a subset of all the non-hack things we want?

DH: This shows the same problems as we discussed earlier.

AWB: This what symbols are...

MM: The "@" is what makes it clear that this is not static

DH: You could say the same thing about brackets.

MM: Always knew @ was dynamic. Opaque, unforgeable and generative.

ARB: (to DH), Once this is defined in a dynamic context it becomes dynamic.

WH: (illustration of perceived hoisting and dynamic rebinding issues)

1
2
3
4
5
6
7
8
9
class C {
private @name;
f() {
for(...) {
x.@name = 5;
}
var @name....
}
}

DH/MM: (discussion of future additions)

BE: We already have with nested function declarations name binding and generativity. Why is it ok for function, but not symbol?

DH: Punning the syntax to make it look static, but it's not.

BE: agreed, that was the fork we took to a bad path, punning "after-the-dot identifier"

DH: People rightly complained early on about static understanding/knowable aspects of syntax. (eg. do I have to look up in scope to know what prop means in { prop: val })

AWB: Most developers will align [] with dynamic property access, vs. .@foo aligns with "static" property name access.

LH: Clarification that we're not talking about the object literal case, but in fact the non-breakable, historic language syntax of property access with []

BE: (Hypothetical future with object [] reformation)

Discussion about implications of hypothetical future with object dereference reformation with ES6 objects.

MM: (to

LH: Moving back to the conservative position to build up from

AWB: Still have symbols

LH: Yes

YK: This is the max/min problem, writ large.

MM: Reminder of workload, wherein ES7 should look like just another phase of development and it's ok to defer to ES7.

AWB: Return to where we were before @-names were introduced

MM: yes

YK: Returning to [iterator]?

Yes.

LH: Still support Mark's proposal (see above)

DH: Only strict mode you get the duplicate error?

MM: true

DH: Could do semantics of strict mode and allow the collision

MM: I don't think this introduces a strict mode runtime tax.

link Conclusion/Resolution

STH will provide a summary.

  • Symbols, unique and private are runtime concepts
  • Only additional syntactic support for them in ES6 is the square brackets in literal forms.
  • Strict object literals throw on collision. (Today, duplicate checks happen at compile time, this will no longer be the case when [prop]: val is used in an objlit)
1
2
3
4
5
6
7
const s1 new PrivateSymbol();
const s2 = s1;
var x = {
[s1]: 33,
[s2]: 44
};

In this context, within the square brackets: AssignmentExpression

(Re: Symbol constructor binding: http://wiki.ecmascript.org/doku.php?id=harmony:modules_standard)

link Experience With TypeScript

Presented by Luke Hoban (slides at http://sdrv.ms/W21q9e)

Findings... Classes: Statics

  • Statics are used frequently
  • Imperative update is awkward when using an otherwise declarative construct

Classes: Privates

  • Frequent asks for Privacy
  • TypeScript added compile-time-only privacy
  • Not quite the same as current private names syntax proposal
    • w/o further sugar private names syntax proposal will feel awkward in practical class

Classes: Automatic base constructor calls

  • Missing super calls

ArrowFunctions

  • Want thin arrow

Classes: Decorators

  • w/ classes available, teams want to use them
  • Biggest block is when existing class library supported some extra "magic" associated w/ class/method declarations
  • No solution yet, not sure what this looks like.

MM: (re annotations) Note that "@" is no longer reserved for ES6...

DH: Point out that we are future proof here.

MM: Let's postpone discussion of the feedback

Modules

  • ES6 modules
  • compiled to JS which uses AMD/CommonJS ...

Modules: Namespaces

  • Two common patterns for large code structure
    1. On demand loaded modules
    2. Namespace objects to reduce global pollution
  • External Modules address #1
  • TypeScript allows internal module re-declaration to grow the object
    • Effectively, a declarative form for object extension with build in closure scope and syntax that matches large scale structuring use cases well.

LH: (the transition from AMD/CommonJS of today to modules a la ES6 is not going to be an easy transition)

Loading order...

LH: When you have circular references, current modules make it appear easy to ignore these issue.

Modules: "modules.exports =" use case

  • Not addressed in TypeScript
  • Critical for interop with existing CommonJS/AMD code
  • Supportive of "export =" syntax proposal
1
2
3
4
5
6
7
8
// something.js
export = function() {
return "something";
};
// other.js
import something = module("something");
var s = something();

DH: (whiteboard)

1
2
3
4
export = function() {};
---------------------------------
import "foo" as foo;
foo();

Async

  • Top requested addition for TypeScript is C# "await"-style async
  • Generators + task.js help, but likely not enough
    • Wrapping is still very unnatural in any real examples
  • But light sugar over generators + task.js would serve
  • Feeds into promises discussion - have to standardize the task objects.

(shows example for task.js and identifies "spawn" which returns a promise object)

Mixed discussion about the history of async discussion through generators, promises, Q.async

link Modules Update

Presented by Dave Herman

(whiteboard)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Modules looked like...
module X {
export module Y {
}
}
// Moved to...
// "foo" doesn't bind anything into this scope,
// just adds to the module registry
module "foo" {
module "bar" {
// no more exporting...
}
}
module "foo/bar" {}
"bar" is not exposed as a property of "foo"
import "foo/bar" as m;

AWB: (clarification of his understanding of the original way that nested modules work)

STH: Yes, that was the way, but there was a realization that much of the earlier approach was flawed and these updates lead to revisions.

One important use case for modules is to configure module references, so that libraries can import jQuery (for example), and get the appropriate version of jQuery specified by the page. Further, it's desirable to be able to use different code for the same library name in different context. Originally, the modules proposal managed this via lexical scope, as follows:

1
2
3
4
5
6
7
8
9
module M1 {
module jquery = "jquery.js";
module something = "something_that_uses_jquery.js"
}
module M2 {
module jquery = "zepto.js";
module something_else = "something_else_that_uses_jquery.js"
}

However, this has two major problems: Inheriting scope across references to external files is potentially confusing, and disliked by a number of people Once we decided to share instances of the same module, the "parent scope" of a module is no longer well-defined

Therefore, we abandoned the idea of inheriting scope across external references. However, this had two consequences that we did not immediately appreciate. First, we no longer had a method for managing this configuration between module names and source code. Second, scoped module names no longer had nearly as much use as originally.

Thus, Dave and I revisited the design, abandoning the use of lexical scope for managing module names, and introducing module names that could be configured on a per-Loader basis.

DH: The registry with the string names is now where the sharing mechanism occurs.

Loader...

1
2
3
4
System.baseURL = "...";
System.resolve = function(...) {
...
};

link Mixed discussion...

  • "global namespace" as in "per realm"
  • <

ARB: This seems to create a parallel global object for modules. Giving up lexical scoping for one global namespace.

DH: There is no way to get rid of the global object

STH: Yes we tried.

DH: (explanation of registry table)

  • Per loader

MM: Separate name registries?

DH: Either are fine

...Provide a minimal set of APIs to allow devs to build there own. ...Sane default behavior ...Default resolution: - baseURL + "Crypto/sha1" + ".js" when no config has been done, this is the base default behavior.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// foo.js
export = 42;
// bar.js
export function bar() {
}
// foobar.js
module "foo" {
export = 42;
}
module "bar" {
export function bar() {
}
}
1
2
3
4
5
6
7
<script>
System.baseURL = "assets/";
</script>
<script async>
import "foo" as foo;
import "bar" as bar;
</script>

WH: What happens if... import "foobar" as fb; (given the above "files")

STH: Answer: fb is an empty object. You also get modules named "foobar/foo" and "foobar/bar" defined.

[WH's question was related to a claim in the discussion that there is no need to have module .js files be distinguishable at the textual level from top-level script .js files]

Mixed discussion w/r loading protocols... and resource loading (files from server, etc) seems to be out of scope?

DH: How is there anything special about JavaScript as the one asset to know about in browsers?

1
<link rel="prefetch"...>

BE: Before imports, prefetch dependencies... but an out of line module import is not a hint, it's a requirement.

DH: Help the browser know in advance about its...

AR: a "prefetch" attribute for scripts? Requests script but doesn't execute.

RW: Until import?

AR: Yes

EF: Don't want to prefetch lazily loaded code later in the program. Don't want to load packages with same dependencies twice.

Bundle A, Bundle B Each share common dependencies. Leads to unbounded number of combinations of pre-build bundles.

A loader should have a way which it can be told, upfront, about the dependency graph. Allowing the system to know all dependencies in advance, so that it doesn't have to compute transitive dependencies for all, every time—to make smart choices about IO.

Ecma/TC39 Meeting – Nov 27 2012

link November 27 2012 Meeting Notes

John Neumann (JN), Norbert Lindenberg (NL), Allen Wirfs-Brock (AWB), Waldemar Horwat (WH), Brian Terlson (BT), Luke Hoban (LH), Rick Waldron (RW), Eric Ferraiuolo (EF), Matt Sweeney (MS), Doug Crockford (DC), Nebojša Ćirić (NC), Yehuda Katz (YK), Erik Arvidsson (EA), Mark Miller (MM), D. Herman, Sam Tobin-Hochstadt JN: (Identify missing members or those that will be here tomorrow)

...Welcome and introductions.JN welcomed members and introductions were made. DC gave us facility and logistical information. Dinner for Wednesday is set for 6 PM.

JN# Previous Meeting Minutes

JN: Review and approve?

RW: Confirm that l have had opportunity to review prior to submission.

JN: Minutes from Sept 2012: Approved.

Review and approval of agenda. Labeled as rev42 will be sent to Patrick for publication.

link ES6 feedback via TypeScript

LH: Move TypeScript feedback update to later, as part of module discussion.

link Review Proposals for inclusion in ES6

JN/AWB: Discussion re: harmony:proposals page and status of listed items.

link Spread Operation accepting Iterables

RW: SpiderMonkey has implemented spread to accept iterables despite the resolution from July. Would like to revisit the resolution.

DH: The implementation was likely just a misunderstanding, will file a bug for these notes.

EA: Let's add to the agenda for further discussion.

link Agenda Discussion

Missing agenda items re-added.

Begin Technical discussion as item 4 on agenda

link Review of new draft spec

AWB: Summary of changes in recent spec. drafts, including:

  • Global declaration instantiation added, "global object + lexical scope" model.
  • Program is now Script
  • Set/Map size is now an accessor
  • Set/Map clear method added

Notably, size is the first accessor defined by the spec.

DH: There will be more accessors defined in the module loader spec.

EA: Ensure no prototype for methods, should behave the same as spec functions.

AWB: Explains how the spec language is laid out for accessors, wherein "get" or "set" is prepended to the section item's title.

RW: (agrees that it's clear to follow)

AWB: This is the first rev. that brings in Proxy, which leads to the restructuring of early sections and internal methods.

Section outlines...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
6. Source
7. Lexical Grammar
8. Type
Abstract Engine
Language
Lex
Syntactic
Vocabulary
9. Helper
10. call/return/scoping
11. expressions
12. statements
13. functions
15. Libraries

Explanation of rationale leading to the restriction and reorganization of internal methods for defining spec behaviors. Leading into the organization of...

link Meta Object Protocol, aka. MOP

Discussing section on invariants and how to redefine in a reasonable way. We need people who are interested in these invariants to make contributions to this section.

8.1 Language Types 8.2 Specification Types

8.3-8.5 Will be moved to after section 10, these define the concrete types

8.3 Ordinary Object - an object that uses the standard MOP semantics in 8.3. example: Objects, Function objects

8.4 Exotic Objects - any object that is not an Ordinary Object, which means anything that specifies the use of something that is not in the MOP. examples: BoundFunction, Arrays, Strings

Standard Object - any object defined by the specification.

WH: why is BoundFunction exotic?

AWB: the special semantics of [[Call]] and [[Construct]]

WH: Does this mean that all built-in functions eg. Math.sin are exotic? This labeling bothers me if the user might be able to define differences between ordinary/exotic

LH: Why aren't all objects exotic?

AWB: initially set out to replace Host Objects, initially defined as anything that has redefined its internal methods

LH: Are there any checks, "is this an exotic object"?

AWB: No, this just simplifies and cleans up the language to that describes an object that has "special" semantics

WH: Do you identify all built-ins as exotic?

AWB: Reads back from Built-In descriptions in rev12

STH: Seems like it's simply a way to ease the pains of editing the spec.

AWB: [Further explanation of

WH: ?

AWB: Every algorithm in chapter 15 is the definition of the algorithms used when [[Call]]. In a situation where we need to reify concepts where we're not sure what the execution context currently is... eg. generators

WH: How does execution context come into this discussion

AWB: The spec needs to be able to discuss these semantics (gives example)

NL/WH: How is this observable if the implementation may or may not be provided in ECMAScript code?

AWB: Only need a means by which to explain the semantics.

I need to be able to talk about the execution context of a chapter 15 function while in a chapter 15 function algorithm

DH: I'm not sure this concept of an exotic object is the best way to go about this.

AWB: At this point we're talking about chapter 15 issues, not specifically exotic objects.

DH: I think this is good to signal to implementors that something different will have to occur.

STH: This is simply a tool to aid in the editing process.

DH: Not an annex, good.

AWB: Correct, the different semantics are grouped where they actually belong.

WH: I still don't understand why there is a grouping of these types of objects.

AWB: Please review the spec... If there are any strong arguments, please share.

AWB/DH: Confirm the subject matter of sections 8.3 and 8.4

RW: (stated prior to beginning of meeting) This change makes reading, understanding and following the varying behaviors easier to follow.

WH: Reading 8.4.6 and can't follow the description...

AWB: There are issues that exist due to prior hacks (not authored by me).

STH/LH: As long as this is just a spec tool, there is nothing wrong with the chosen categorizations.

AWB: For those of you reading the spec, please re-familiarize yourself with the new terminology.

LH:

AWB: The risk for semantic change... some methods renamed, some may have different behaviors. No change to observable semantics

DH: Don't remember the proto climbing refactoring

AWB: Tries locally, then same operation on next level. Each step up is observable via proxies.

DH: not web dependent

WH: if it's not visible, why do implementations need to change?

AWB: In the presence of proxies, proto climbing is visible. The difference... What [[Get]] in the old system did was loop, instead of recursion. If a prototype was a proxy, the trap would never be invoked. In the new system, it will. The property access system needed to change to support this...

DH: We'll get feedback from proxy implementors

AWB:

MM: There are two engine based proxy implementations, SpiderMonkey and v8—let's wait to discuss the impact.

BT: So there is a low risk of semantic change in 8.x? (with no regard for proxies)

AWB: Should be no observable semantic change and this should be confirmable with tests and reviewers. ...Will add a description of what should be observable and not.

Another change happening in this edition, is specifying where each exception is thrown. Previously this was implicit, but is now explicit.

WH/AWB: review 10.2.1.2.6 use of ReturnIfAbrupt(value)

LH: was there concern of ambiguity before? Seemed clear...

AWB: There were places where it was unclear where the the exception should be thrown, Mark had identified the loop in ??

...Discussion about explicit exceptions

DC: Need to break.

WH: Throw on string concat over allowed length?

...Discussion about ReturnIfAbrupt...

LH: Is this a maintainability issue? If a new leaf addition is defined that uses ReturnIfAbrupt, do you have to check all call sites?

AWB: The work is already done.

... Discussion.

link Break.

link Meeting Notes - Publish to wiki

(side discussion, but valid to document)

link Conclusion/Resolution RW to publish meeting notes to ecma wiki (in addition to publishing on es-discuss and submission to ECMA)

link Internationalization Update

NL: (Summary of changes based on feedback) Spec document submitted to general assembly for approval. HTML version of the spec has been prepared, will be posted to ECMA site after GA approval. Demonstration of test402 (INTL spec testing) running on Firefox (special build, not in Mozilla repository yet).

NC: v8 Implementation has regressed, due to clean up of defineProperty use.

LH: Has an IE plugin impl., next phase is to implement directly

LH: Should have discussion re: spec intention that all checks whether this is an instance Object, is this cross-realm? or this realm?

AWB: Yes, let's discuss this. Clarify...

NL: Any questions re: Internationalization 1.0?

JN: What is the plan w/r to hosting and maintaining test402

NL: Any company that wants to invest resources into contributing tests and maintaining?

BT: Can't say specifically, but Microsoft will certainly be contributing tests

NC: Same for google

JN: Anything for submission to the GA?

NL: We'll provide a technical report of some form for submission. Will provide the number of tests, (approx) and that coverage (missing and not) is understood.

link International 2.0

(get slides from NL)

(1) Complete Spec Sep/Nov 2013 TC39 approval March 2014 GA approval June 2014

MM: Be aware of possible delays in ES6

(2) Prioritization

(3) High (Or part of ES6?)

  • Unicode normalization
  • Case Conversion
  • Character properties in RegExp or as API

Discussion re: unicode, changes in ES6 to RegExp re: unicode No changes are in draft yet.

(4) High (cont)

  • IANA timezone IDs in DateTimeFormat
  • Chrome 24+ has impl
  • Message Formatting, including gender and plural handling
  • Not clear how template strings fit in

RW/NL: agree to loop Alex Sexton into the work on message formatting specification.

(5) Wait

  • DateTimeFormat improvements
  • Need feedback on 1.0
  • Pattern strings, highlevel specifiers
  • Info for date pickers
  • Date intervals, relative dates, durations?
  • Expose ToLocalTime?

(6) Wait

  • Resource Bundles
  • Needs investigation
  • Maybe module system can be used?

WH: How are resource bundles different from JSON?

NL: That's generally how they are stored, the challenge is loading the right bundle for the application's current locale

DH: can this be stored compressed in a binary format?

AWB/LH/YK: (discussion and agreement on HTML/CSS involvement in resource bundling is too browser-centric)

WH: Rather than providing a method that loads a bundle from some web page (which will likely clash with how a particular web server is structured), provide utilities such as decoding a bundle from a string and selecting the right bundle (e.g. the current language's) from a list of bundle names.

MM: Abstract the problem to a data loading issue

EF: Whose job is it to define the information in a resource bundle?

EF/NL: generally the library or application using the data has to define its structure and provide bundles for the locales it wants to support; there is an issue when third parties want to add more locales

(7) Medium

  • Text segmentation: word and line breaks
  • Editors, offline indexing...
  • Chrome already has impl
  • Browsers names for languages
  • Display names for languages, countries, scripts
  • Number parsing - no currencies/percent/dates

MM: Presumably there are other standards bodies that we can use the data from.

WH: This gets into the political issue of what countries are called based on local law. Is Taiwan a country?

(8) Medium/Low

  • Calendar Support
  • Info for date picker
  • Conversion between calendars
  • Calculations within calendar (add 3 days)

(9) No

  • Title case, too many house rules
  • Language Detection, too specialized
  • Encoding detection and conversion, value decreasing.

(10)

  • Script reording in Collator
  • Pseudo-numbering systems in NumberFormat and DateTimeFormat

(11) Approval?

JN: Who is working on this?

NL: First meeting had representatives from Mozilla, Google, Microsoft, Amazon.

JN: Will provide minutes of meetings to ECMA?

NC: Yes.

JN: Despite potential operational changes from ECMA, let's move forward with this project. Continue to report as adhoc group via this group.

link Conclusion/Resolution

TC39 Approves to move forward with 2.0. NL will submit slides to ECMA for minutes record.

link String Normalization

http://wiki.ecmascript.org/doku.php?id=strawman:unicode_normalization#add_normalize_method

NL: AWB has removed a number of references to normalization from the current spec that did not reflect reality

String.prototype.normalize(form)

MM: Any sequence of utf-16 has a valid, specific normalization?

NL: Will have to check if the normalization spec has anything about unpaired surrogates.

MM: Either we make the function total, in the sense that it always returns a string, or total in the sense that we define where it throws exception.

NL/LH: (agree w/ always return a string)

NL: Are we in agreement to spec this?

MM: Requirements: (moved to resolution)

link Conclusion/Resolution

Yes, requirements:

  • total,
  • deterministic
  • idempotent normalization (normalizing the result of normalization again will return the first result)

WH: Note that Unicode got this wrong a while back (their normalization algorithm wasn't idempotent, and it didn't even form proper equivalence relations). They fixed it since then and now explicitly state that it's idempotent.

link String Case Conversion

http://wiki.ecmascript.org/doku.php?id=strawman:case_conversion

LH: Why isn't this in the Internationalization standard?

AWB: Is there a reason this isn't in the Intl 1.0?

NL: Case conversion wasn't considered in original scope for Intl 1.0; we then forgot to add it when respecifying String.prototype.localeCompare and friends.

RW: There is a Case Conversion item in Intl 2.0, is this the same?

NL: Correct, but these functions are in Language spec. Should this be added to ES6?

AWB: Don't think that we should start moving Intl into ES, or at least not until ES7

NL/LH: Not being in ES6 doesn't prevent implementation or spec authoring.

LH: Doesn't need to be in the wrong spec just to move forward.

link Conclusion/Resolution

Goes in Internationalization but doesn't prevent specification or implementation.

link Eliminate ToUInt32() warping on array access

AWB: Sparse parameter on Array iterator constructors (eg. Array.prototype.keys/values/items that determines whether or not "holes" are included in the iteration.? Can we eliminate functions returning Reference values from the specification

AWB: Arrays use ToUint32, which does modulo arithmetic.

WH: Yes, but it doesn't actually warp indices. Ones larger than 2^32-2 are not array indices; they're not treated modulo 2^32.

WH: Also note that strings such as "0.0" and "007" are intentionally not array indices either, even though they're within the array range. The array index code checks that the value round-trips to a number and back to the same string; this is what keeps indices over 2^32-2 from warping.

MM: What are the practical benefits of this?

AWB: 2 Things, we could do this at 2^53 and truncate there instead of warping

MM: Is there a history of implementors that have worked out these issues?

AWB: Every new array(like) operation needs to have this behavior

DH: Concern that this will break the web

AWB: IE had a problem for a long time that went nearly unnoticed.

MM: strategic to postpone this cleanup until we have integers. Don't see a reason to make this change

DH: Concerned about code that would even have arrays this large

AWB: The point is to avoid craziness after 2^53

MM: What is the handling of the 2^53 edge condition that this change will benefit?

AWB: I have to review the spec and can follow up tomorrow.

Look at 15.4 of ES5.1, when you go over the edge, results in expand properties being set on the array. Additionally, the 2^32 edge condition:

1
2
var a = [];
a[Math.pow(2, 32) - 1] = true;

link Conclusion/Resolution

Tabled until AWB has further impact research.

link The prototype/constructor object model supporting Generators/use of instanceof with generators and generator instances

AWB, presents UML diagram to illustrate...

The Generator Constructor doesn't need a global name. Assume it's accessible at System.Global.

Each generator function has a unique prototype object with own properties for next, send, throw, close, etc. These prototype types may share references to the built-in mplementations of those methods.

1
2
g1 instanceof Function; // true
g2 instanceof Function; // true

But no way to test if either g1 or g2 is a generator function rather than an ordinary function. ...

Possible Solutions:

  1. Make Generator a subclass of Function, allows instanceof checking (on some kind of special System object)
  2. Make a global built-in Generator constructor
  3. @@hasInstance(): void

Anomalies...

  1. instanceof will be true for non Generator functions
  2. g1.constructor === "Generator"?

DH: If we go against the behavior of the language we'll end up with...

MM: Agree up until the reflective Generator

DH: Function creates function, Generator creates generator

YK: Anything other than that is pure WAT.

AWB: Need to get our terminology straight.

MM: Going forward, we've created this class system... Having Generators be a subclass...

lost track, sorry. Hope Mark can fill this point in later.

YK/MM/LH: like...

1
2
class Generator extends Function.prototype {}
class g* extends Generator {}

DH: The way to check "is this a generator?"

1
Object.getPrototypeOf(f) === "Generator";

MM: Of all the things we're talking about, creating Generators reflectively is the least concern. Something like...

Function.makeGenerator(...); returns generator function

... If that was important to provide, but likely not.

MM/LH: Generator is a zero-arg, no-op.

LH: Reiterates that class g* extends Generator {} clarifies thinking about the diagram

DH/LH: (Discussion of this inside Generator)

MM/AWB: (Converge on diagram of inheritance relationship)

DH: Which parts do we surface as public API?

MM: Abstaining.

DH: Important to retain Python naming to avoid WAT. Ok with not surfacing anything to public API

WH: Would like to at least expose "Generator". [Note: the object I was referring to got renamed to "GeneratorFunction" later in the discussion and further down in the notes here.]

DH/WH: (Disagreement on exposure of public API)

AWB: Need a value for .constructor

DH: Ok, .constructor dictates the requirement.

MM: Does this mean that if you call the Generator constructor with a yield?

AWB/RW: Error

??

DC: Are we adding Generator because it qualifies as important enough to stand on its own?

DH: Reflective evaluation is powerful enough to stand on its own. A huge gulf between with

MM: There is no immediate benefit...

WH: It's easier to include then to exclude it, for spec benefit.

MM: Agreed, only benefit is specification symmetry.

WH: Function does reflection, so it makes sense.

MM: Consensus on exposing GeneratorFunction via some imported module?

All: Yes.

MS: Can I determine if an object is a generator function?

DH:

1
2
3
f instanceof GeneratorFunction;
f.__proto__ === GeneratorFunction.prototype;
f.__proto__ === (function *() {}).__proto__;

link Conclusion/Resolution

Ecma/TC39 Meeting – Sep 20 2012

link September 20 2012 Meeting Notes

John Neumann (JN), Mark Miller (MM), Norbert Lindenberg (NL), Nebojsa Ciric (NC), Allen Wirfs-Brock (AWB), Luke Hoban (LH), Paul Leathers (PB), Sam Tobin-Hochstadt (STH), Andreas Rossberg (ARB), Brendan Eich (BE), Erik Arvidsson (EA), Dave Herman (DH), Yehuda Katz (YK), Rick Waldron (RW), Eric Ferraiuolo (EF), Matt Sweeney (MS), Doug Crockford (DC), Alex Russell (AR), Rafael Weinstein (RWS), Waldemar Horwat (WH), Rick Hudson (RH)

link Object.observe Update

(Presented by Rafael Weinstein, Google)

REQUEST SLIDES!

Aug 18th, Released an experimental implementation, spec complete, via special Chromium Build. https://github.com/rafaelw/v8

Updates to strawman:

  • Updating [[Prototype]] qnqueues a "prototype" changeRecord

ChangeSummary.js (experimental library) https://github.com/rafaelw/ChangeSummary

  • Prototypes "diff" view of changes
  • Correct observation of "paths" (eg. o.foo.bar.baz)
  • Array splice projection (minimal ops to syn)
  • Basis for framework usage

YK: Question about splice projections being built in. When splice happens, many records change... is pathologically slow. Fine for v1 to leave it to library code.

RWS: Opted to leave this out... ...explains n^2 issues that arise when changes to an array occur. ...explains rationale for leaving out for the foreseeable future and allow library authors to handle as they see fit for the time being.

DH: How to make a policy decision about "what" to look at in the change of an object. Agrees with this v1 decision, in favor of allowing library optimization patterns to emerge. [We can't determine the "policies" before the needs are fully understood]

AWB: Not just large scale libs, but everyday data type abstractions.

RWS: Sounds like there are specific issues?

AWB: Yes, but not to be addressed in this timeline

MM: Is the synthetic changeRecord adequate for the level of abstraction you may require

AWB: Yes, sufficient.

RW: (shared anecdotal experience writing "Fact" with Object.observe: https://github.com/rwldrn/fact )

RWS: (presenting demo)

ADD LINK

Discussion about "read" notifications and performance concerns.

YK: Willing to move Ember, despite the scale

EF: Did Angular replace all dirty checking?

YK/RWS: Not really possible to remove all dirty checking.

link Observing Computed Properties and Dependencies

RWS: Believe that it is not in scope now or ever.

link Tuning Spec, Implementation Complexity

RWS: ...Is hoping to progress the strawman to harmony. A few slides that discuss remaining issues.

LH: These represent concerns and agreements of several committee members who have been involved.

link Synchronous Delivery?

NO.

link Security Mitigations

Object.getNotifier( frozenObject ) returns null (Out of 3 options: return null, throw, or do nothing notifier)

WH: What happens when the argument is a Proxy?

RWS: Returns the Proxy's notifier

STH: An invariant maintained internally, that if the proxy is frozen it ensures the target is frozen.

ARB: Not sure if this is true.

MM/STH: The proxy cannot say it is frozen if the target is not. Can the proxy say its NOT frozen if the target IS?

WK/MM/STH: Proxy can say it's frozen if AND ONLY IF, the target is frozen.

MM: If the notifier is derived, then the object is frozen, the notifier will continue to work as expected.

Creator of an object:

  1. creates an object
  2. gets the notifier
  3. freezes the object
  4. releases the object

This is an intended mechanism of the Proxy proposal

WH/AWB/MM: Discussion about notifications from frozen objects. The use of the notifier should ONLY be from the provider of the abstraction.

link oldValue

Most use cases would create copy of all observed data

WH: What about accessors?

RWS: accessors don't notify

WH: That's bad.

MM/EA/RWS/AWB: No, this is intended.

RWS: (Explains that getNotifier can be used to build synthetic events for accessors)

RW: Yes, accomplished this while experimenting with "Fact"

RWS: (Revisits demo to show example of what an abstraction over this looks like)

YK: (Supported use story in Ember)

...Mixed discussion about far future notifier patterns:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// no-op, just for example...
function handler( changeRecord ) {
console.log( changeRecord );
}
class Foo {
private @x, @notifier;
constructor(x) {
this.@x = x;
Object.observe(this, handler);
this.@notifier = Object.getNotifier(this);
}
get x() {
return this.@x;
}
set x(v) {
this.@notifier.notify({
object: this,
name: "x",
type: "updated",
oldValue: this.@x
});
this.@x = v;
}
}
var f = new Foo("hello");
f.x = "Hola";
// synthetic change event fired with "changeRecord"
// defined in the set x() accessor

Discussion regarding the feasibility of adding to ES6.

DH: Doesn't need to be in spec to prototype

BE: Worried about sheer weight of work involved in Allen's spec writing.

RH: Moving from strawman to proposal/spec is meaningful to implementor teams.

[some discussion about whether the above construction pattern has efficiency problems; needs implementation experience]

link Conclusion/Resolution

Push for prototype implementations (Chrome already in progress). Encourage others to do the same

Officially Promoted to proposal for ES7.

link Grammar Validation

(Presented by Brendan Eich, Mozilla, Waldemar Horwat, Google, Rick Waldron, jQuery/Bocoup)

Overdue for grammar validation, would be ideal to re-validate.

WH: The following is ambiguous because yield is not a reserved word. It can't even be lexed: boom = yield/area/ height; Note that the current semantic restrictions on where yield expressions can go don't help because they apply after the program has been parsed; with this example you can't even get to the lexing and parsing stages.

Resolution on the yield issue?

link Conclusion/Resolution

AWB will refactor grammar so that yield can only be used within the context of a generator function and yield will not be usable as an identifier there. This will require essentially doubling the number of grammar rules in an analogous way to how the no-in rules are handled today, but on a much larger scale.

BE: Need wider, complete validation that takes into account ASI and noIn.

BE/AWB: Who is going to own this?

link Conclusion/Resolution

Waldemar is going to try to work on this

link Formal Parameter Scope

(Presented by Brendan Eich, Mozilla)

With regard to default formal parameters...

Previously, all to the LEFT are in scope, let *:

1
2
3
4
5
6
7
8
9
var b = "outer";
function f(a = x, b = a * b, c = c * g() ) {
/*
three scopes:
(a),
(a and b)
(a, b, c)
*/
}

Realistically, it should desugar, scope rules included:

1
2
3
4
5
6
7
8
var b = "outer";
function f(a, b, c) {
if ( a === void 0 ) a = x;
if ( b === void 0 ) b = a * b;
if ( c === void 0 ) c = c * ();
function g() {} // will hoist
}

AWB: functions will hoist, let and const will be in the dead zone and will fail, var will hoist and initialize undefined

BE: Can we agree to get rid of let *?

With let x this is an error:

1
2
3
4
function f( a = "a" ) {
let a;
var a;
}

Not let bindings

1
f(a = b, b = 3)

let scope would break var scope: bad let scope with magic to break var scope: bad

ARB: (whiteboard)

1
2
3
4
5
function f(x = (y = 42), y = 41){}
f();
42, 42

DH: My understanding was that temporal dead zone should error all the way to actual "blessed source code" where the binding is initialized.

Remind why only "no read before write"?

BE: 2 years ago in redmond agreement.

AWB: (explains the rationale and current semantics)

DH: is this a distinction worth making, for let, when we're trying to say that let is a better var

MM: let guards were the original reasoning.

DH: let guards should be different from just let

MM/WH: No, they shouldn't be different.

STH: Need to provide an argument beyond that

WH: guarded let should be not be different from a let. One common option for a guard must be a bottom type that lets through anything, but that's impossible with the same behavior if a guarded 'let' differs from a plain 'let'.

DH: This is far future, hypothetical

MM/DH: related to temporal dead zone discussion.

LH: The temporal dead zone opposition is perf

WH/DH: (discussion of complexity for let and const)

DH: I dont want to alienate developers for no good reason (gives supporting argument)

MM: Better to return undefined or immediately error to show where the mistake is made

DH: Want to simplify to "no read before write". The model of let creates a binding and = assigns a value to it. There is no way to explain that this = is different from that =. Refers to Alex's JS is top-to-bottom.

MM: But it's not because you can forward-call functions, because JavaScript allows you to interleave function and var initializations and assignments throughout your program.

DH: (missed not about read barrier)

WH:

ARB: Trying to simulate C semantics within the constraints of a dynamic system.

AWB: Yes, this was the agreement before temporal dead zone. throw if used before init.

MM, WH: Halting further discussion. We frequently eat up time on subjects like this that have already reached consensus. Let's postpone unnec revisitings.

AWB: Ok to revisit for valid reasons...

YK: worried that if no performance issues are found then it wont be revisited.

AR: Points out that there might be real issues with developer understanding. (cites some example, ask to share?)

[[[[[[[[[[[[[[[[[[[[[[[ Temporarily, this happened: Conclusion/Resolution

  • var bindings and are in scope within the function
  • cannot use let to shadow a parameter
  • defaults can refer to any top level binding ]]]]]]]]]]]]]]]]]]]]]]]

link Conclusion/Resolution

Revisit when data is gathered, re: perf or unexpected behaviours

link Array.of Rename?

Recent post on es-discuss from user that doesn't like Array.of

Array.of has been implemented in all of the es6 shim libs (Paul Miller, Axel Rauschmayer, Andrea Giammarchi and others...)

link Array.of()

Makes sense, nice to say and explain. When I reason about a program:

"Here we have an array of elements" (elements, items, numbers, strings)

link Conclusion/Resolution

No change, no revisit.

If we do Foo.new(), it must be identical to new Foo().

link Thin Arrow?

(Presented by Brendan Eich, Mozilla)

We have the fat-arrow, supported by Kevin Smith's research, it's a win. Some voices in the community don't want the unexpected behaviour of the bound lexical this

class, concise methods and fat-arrow are all new, powerful and composable function binding forms.

WH: Don't want two slightly different concepts with a confusingly similar syntax. It would be too difficult for casual users to remember which arrow is which [in the same way as I can never remember in C++ which variant of the ++ operator overload takes an extra dummy argument].

?: Then let's use fat-arrow with an extra 'this' parameter to stand for thin arrow.

WH: That would address the confusion, but is still unnecessary featuritis and doesn't even save much in terms of text, which was its original reason for existence. Saving a couple characters here is not worth complicating the language.

link Conclusion/Resolution

Consensus holds on fat-arrow

link Existential Operator (strawman discussion)

(Presented by Brendan Eich, Mozilla)

Significant desire include a null and undefined check in syntax/operator form (a la coffeescipt)

1
2
3
o = {}
r = o?.p.q.r
r = o?.p?.q.r

Mixed discussion about the needs and use cases as they apply to coffeescript code.

ARB: This is non-compositional

1
2
3
4
o = {}
r = o?.p.q.r
r = (o?.p).q.r
r = o?.p.q.r()

Results in...

1
2
3
4
5
var o, r;
o = {};
r = o != null ? o.p.q.r : void 0;
r = (o != null ? o.p : void 0).q.r;
r = o != null ? o.p.q.r() : void 0;

Non-starter.

DH: Why not an operator that needs to be explicit?

1
o?.p?.q?.r

LH: Why would you ever even use it on the first?

BE: Forget all of the problems with coffeescript's impl, the need exists.

YK: In the common cases, where it works, it works well. Where it doesn't, it falls apart unexpectedly.

WH: What about other contexts such as p?[x], p?.q[x], and p?(x) ? [Note that grammar problems arise for some of those.]

General agreement.

link Conclusion/Resolution

Seems useful, but not now. Semantics are unclear

link Generators

link thisBinding

Generator thisBinding is the thisBinding of the original generator call.

1
2
3
4
5
6
7
class MyArray extends Array {
*iterator() {
let last = this.length;
let next = 0;
while (next < last) yield this[next++];
}
}

link Generator object API?

1
2
3
4
5
6
7
8
9
class MyArray extends Array {
*iterator() {
let last = this.length;
let next = 0;
while (next < last) yield this[next++];
}
}
new MyArray(4, 8, 15, 16, 23, 42).iterator();

...returns a generator instance that will have generator methods

MM: Take a care to expose the APIs that you expect to expose.

DH: Agrees

LH: Specify the generator?

BE: Allen is worried that normative spec will require generators when it's unnec.

DH: spec a simplified generator interface, without semantics, just to define the method interface.

MM: what is the minimal method interface?

DH: send, throw, close

Discussion around specifying a generator contract.

DH: Don't specify what can't be put on generator objects.

AWB: Need something for spec

YK: If everyone implemented iterators with generators

DH: Not super worried about this...

link Conclusion/Resolution

The spec should not specify built in iterators to have 3 extra generator methods (ie send, throw, close) (Currently in draft, needs to be refactored)

Notably: Significant dissent on throwing exceptions for control flow.

Continued discussion of note...

LH: Using a debugger, break on throw, exceptions. Want to catch at the point where they are thrown... on a StopIteration, do I see internals?

DH: Up to the debugger to determine whether or not it should expose

LH: (whiteboard, example misuse of iterator)

BE: Historically, not an issue.

YK: (Question about use of in-band return?)

LH: if this is not an issue, then why not specify

Discussion about protocol specifications, where precedent exists.

link Supplemental tests for Tests 262

SpiderMonkey and v8 are writing tests, can contribute back.

Need parity, it's hard.

link Goals

AWB: January, spec: feature complete.

LH: Multiple implementations?

Concerns about removal of new additions when there isn't enough evidence to support the removal.

Too soon to make cuts when we don't know what to cut.

Ecma/TC39 Meeting – Sep 19 2012

link September 19 2012 Meeting Notes

John Neumann (JN), Mark Miller (MM), Norbert Lindenberg (NL), Nebojsa Ciric (NC), Allen Wirfs-Brock (AWB), Istvan Sebastian (IS), Luke Hoban (LH), Paul Leathers (PB), Sam Tobin-Hochstadt (STH), Andreas Rossberg (ARB), Brendan Eich (BE), Erik Arvidsson (EA), Dave Herman (DH), Yehuda Katz (YK), Rick Waldron (RW), Eric Ferraiuolo (EF), Matt Sweeney (MS), Doug Crockford (DC), Alex Russell (AR), Rafael Weinstein (RWS), Waldemar Horwat (WH), Tom Van Cutsem (TVC, phone)

Recap of Sept 18th notes.

link Proxy

(Presented by Tom Van Cutsem, Free University of Brussels)

link Enumerate Traps Return Types

TVC: change return type of enumerate() trap from array-of-string to iterator. Requires waiving the check for duplicate property names

link Conclusion/Resolution

Drop the duplicate property check. enumerate() trap returns iterator.

link Revokable Proxies

TVC: The Problem

In a nutshell: with direct proxies, one can no longer write a caretaker proxy that nulls out a pointer to its target once revoked. This means that the target can no longer be garbage-collected separately from its proxy.

As pointed out by David Bruant, caretakers are often useful precisely for memory management, where one uses revocation of the caretaker to release the underlying resources, as described here.

Such caretakers were easy to define in the old Proxy design, since the link between a proxy and its target was fully under the control of the handler (i.e. fully virtual). However, with direct proxies, the proxy has a built-in, immutable reference directly to its target. This reference can’t be modified or nulled out.

Proposed Solution

Provide an extension to the Proxy API that allows scripts to null out the proxy-target reference. Of course, the API must be designed with care so that this link can’t be nulled out by any old client of the proxy. Only the creator of the proxy should have the right to revoke it.

Because revokable proxies appear to be a niche abstraction, we propose to introduce a separate Proxy constructor dedicated to creating revokable proxies. Proxies created with the regular Proxy constructor would remain unrevokable.

Proposal:

  • Introduce a new constructor function RevokableProxy, next to Proxy.
  • RevokableProxy(target, handler) returns an object {proxy: proxy, revoke: revoke}.
  • revoke is a zero-argument function that, when called, revokes its associated proxy.
  • A revoked proxy becomes unusable in the sense that any operation that would trap to the handler instead throws a TypeError.
  • Revoking an already revoked proxy has no effect.
  • Once a proxy is revoked, it remains forever revoked.
  • A revoked proxy drops its target and handler, making both available for garbage collection.

MM: We missed this in the change to Direct Proxies, thanks to David Bruant for identifying

...Bikeshedding the spelling of "Revokable"

MM, WH: Should be "revocable" ?: "Revokable" would seem like a typo to many folks, as it's an unusual spelling of the word.

LH: This is bringing another constructor...? Do we want to duplicate all of the functionality?

RW/DH: Agree this is an issue.

MM: static on the Proxy object?

Yes.

... Discussion about the naming.

Proposal: Proxy.revocable

DH: perhaps too academic? Consider alternative names: nullable, ...? MM: We can decide later.

Should Proxy.revokable return the tuple as an array or an object? MM: object: non-positional + Javascript has sufficiently lightweight notation for objects. STH: then the name "revoke" is part of the API

Question as to whether we really need two kinds of proxies. BE: yes, non-revokable proxies have less trap overhead (no null-check)

Discussion about whether revokable proxies introduce new ways for interceptable operations to behave.

WH: Not sure about this as a feature, w/r to future hostility...

  • eg. if "===" would trap to the handler how does this work with that?

MM: trapping "===" would be a significant change on its own, independent of revokable proxies

TVC: The only type test that is affected is typeof: once the proxy is revoked, it drops references to its target and its handler, so it can no longer forward the typeof test to its target

BE: It remembers "function" or "object" TVC: right

DH:

RWS: Does this problem exist...

STH: revokable proxies don't add any new semantics b/c you can already write a direct proxy that throws the same error on every operation (it just uses more memory)

WH: Direct proxy, not allowed to muck with

MM: Are

TVC: Equivalent to a handler that implements all its traps to unconditionally throw

STH: RevocableProxy adds no new semantics to the language. except for allowing the proxy to be nullable

WH: I'm not sure about it

DH: He jsut gave proof.

MM: The semantics change to the handlers always throwing on all traps.

WH: Are there other traps affected by this?

TVC: New traps added last meeting will not be affected.

WH: So, a frozen object can "unfreeze" itself?

MM: No

WH: An object that is frozen can later refuse that its frozen Concern about trapping isFrozen etc.: these tests are no longer stable. MM: but are still fail-stop. The integrity guarantee (i.e. that it always returns a correct answer) is more important than the availability guarantee (i.e. that it always returns an answer)

Alternative to trapping isFrozen etc.: cache stable outcome of certain operations in the proxy, and afterwards no longer trap.

STH: After the first time isfrozen is true, mark to no longer call.

AWB: would preclude valid use cases that e.g. want to log all requested isFrozen operations.

Is there a situation where revoking allows an operation to throw where it previously couldn't with non-revocable proxies? TVC: should not be the case

MM: Specify that...

The revoke action is observably equivalent to changing the state of the handler to always throw on all traps.

WH: An uneasy feeling about what else is hiding

BE: Mark and Tom have significant work on this issue.

MM: The ability to evict a subgraph is important once frozen, stop trapping. once non-configurable, non-writable data, the value continues to be accessible. this loses the garbage collectability of membranes

...

DH: Question of clarification re: two constructors, are they necessary because there is no way to return two things from a constructor.

BE/MM: They create things that are just too different

BE: There is no mutable state within the proxy that is actually "mutated"?

TVC: not currently. If we want to pursue the above idea where a trap is disabled once its stable outcome is observed, then the proxy would need to be mutated.

MM: If you could falsly claim to be not-frozen after being frozen, then there would be issues with reliability, but doesn't exist. ...

MM/AR: (discussion about execution points in ES5)

AR: If you have a file name object, hand it into some API, it might throw, it might not throw... how is this different that what happened before?

WH: Again, still not sure about effects throughout proxy

MM/AR: (discussion about frozen object stability)

AR: Why do we care about the stability of frozen object w/r to revocability?

WH: (summary) Not clear what the security consequences of revoking a frozen object, either via a revocable proxy or via traps, are; this hasn't been thought about.

MM: This has been thought about and discussed off-line.

link Conclusion/Resolution

  • we want revocable proxies
  • further discussion is needed on revoking frozen objects, either via revocable proxies or via traps

link Proxy and Private Names

TVC: We don't want Proxy to inadvertently leak private name properties.

In Redmond, we discussed that we would seperate string properties and private name properties into separate traps.

Later determined that this would become cumbersome.

Proposing to add a third argument to the Proxy constructor: a "whitelist" of private name properties that are allowed to be trapped.

WH: unique vs private names? STH: The primary purpose of Names is to avoid name clash and non-forgeable. Uniques should be reflected, private: not.

WH: What makes them non-forgeable

STH: They are objects

DH: And are as non-forgeable as objects,

WH: Why do we need both? Unique, Private?

AWB: They are both useful

STH: Unique names give you actual unforgeability

MM: as opposed to the "unguessability" of randomly chosen strings

DH: About the whitelist, instead of requiring a WeakSet, can it be anything that can be passed to a WeakSet, like an Array?

MM: Should probably use a WeakMap...

EA: An object that has a method that takes the public name string and returns the private name object, if you have access to that, you can extract the private data.

STH: Erik is right, but it a

MM: if we don't drop the .public property, don't need the whitelist but instead just the resolvePrivateName trap. If we stick with the whitelist, don't pass the .public property to the resolvePrivateName trap

TVC: Why is it a WeakSet? Because we dont want someone to provide their own collection that can extract the private data.

TVC: Why is there a resolvePrivateName trap? Say an operation is performed on a proxy involving a private name, and the proxy doesn't know this private name. Two reasonable options: 1) forward to target, i dont see results, I dont care. OR 2) throw exception. A policy decision to be made by the handler: when working on a private name that we dont know about, forward or throw?

DH: Should champions take this offline?

STH: It's pretty important and could mean a significant simplification.

WH: Would like to get rid of the public/private property flags

DH: for notational convenience, would be great if one could pass an array literal as 3rd arg TVC: could specify that if 3rd arg is an array-like, we copy its elements into a built-in WeakSet WH: that would be confusing: names later added to the array-like won't get added to the internal WeakSet

AWB: Not clear how using a built-in WeakSet will protect, what if it's been redefined? Are WeakSet methods non-writable? TVC: we need to specify that the proxy calls the original/intrinsic WeakSet.prototype.get method.

STH/LH/RW: Will need to spec WeakSet

link Conclusion/Resolution

Yes to third arg for whitelist, pending details to be worked out by Proxy champions.

Expect to remove the "public" part of private names.

link WeakSet

DH: Clear that we need WeakSet to match WeakMap (Set and Map)

AWB: Need to assure that WeakMap and WeakSet are not redefined?

RW: Use cases in node programs where I'm using WeakMap made it apparent that it is possible to leak via redefinition.

link Conclusion/Resolution

Needs to be designed, as part of the whitelist feature's needs.

SpiderMonkey tracking bug: https://bugzilla.mozilla.org/show_bug.cgi?id=792439

link Syntactic Support for Private Names

(Presented by Allen Wirfs-Brock, Mozilla)

Slides: https://members.ecma-international.org/get.php?group=TC39&file=2012_sub_tc39-2012-066.pdf

link Private Names & @Names

link Unique/Private Names

  • Unique and private names (aka symbols) are ES6's solution for objects that need to expose props that have limited or controlled acccessibility.

  • Currently no syntactic support for definition of use

  • Imperative code patterns for using names dont mesh well with declaratinve object/class definitional forms.

eg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const secret = Name();
let o = { secret: 42 }; // does not define a "Name" prop
class MyClass extends Yours {
secret() {
this.mine();
super[secret]();
}
}
// Not allowed:
MyClass.prototype[secret] = function() {
super[secret]();
};
//... Because super is banned outside of class

link Computed Property Names for Object Literals Were Abandoned...

1
2
3
4
5
6
7
8
9
const secret = 42;
let o = { [secret]: 42 };
class MyClass extends Yours {
[secret]() {
this.mine();
super[secret]();
}
}

Issues:

  • Allowed arbitrary expr in prop name def position
  • Allowed aliasing of string valued prop keys
  • Permitted same key to duplicate
  • Future hostile: ties prop def to indexing (See: object model reformation)

link Proposal At-Names

Slides

  • An At-Names is an IdentifierName that is lexically prefixed with @
  • At-Names are const bound to Name values by new declaration forms
1
2
name @x, @y;
priv @secret;
  • Such declarations implicitly create Name Objects
  • ... Missed slides

link At-Name References

  • At-Name can appear in any context where an IdentifierName would be interpreted as a literal property name.
    • As a prop name in object literals/class defs
    • After . in MemberExpressions
  • Lexical scoping rules resolve such At-Name references to a Name object value.
1
2
3
4
5
6
7
8
private secret;
let o = { @secret: 42 };
class MyClass extends Yours {
@secret() {
this.mine();
}
}

link At-Names in Primary Expressions

  • When used as Primary expression, an At-Name... (see slides)
1
2
3
obj.@secret
obj[@secret]
// same thing

link Name Declarations with Initializers

  • In a name/private declaration, each At-Name may have an initialization expression.
1
private @secret = NameBroker.provideName(secretcode);
  • The initializer must evaluate to a name object
  • Primary use case is initializing an At-Name to a name provided via a function call or other computed value (the provided name or computed value is "secretcode").

DH: Concern about keyword naming, "private" (worried about contextual keywords)

AWB: naming can be bikeshedded, but whatever it is, there is no ambiguity because:

1
foo @IdentifierName

Is always: "keyword [space] '@'"

DH: You've won me over

LH: Not sure this goes "far enough" to warrant the addition.

MM/AWB/YK: (discussion about simplification)

DH: (whiteboard)

1
2
3
4
5
6
7
8
9
10
11
let o = {
private @foo: 42,
m() {
return this.@foo;
}
}
o.m(); // 42
// As seen via inspection (REPL, console)
{ m() {} }

...Discussion about varying semantics lacking in previous proposals.

MM: Cannot avoid runtime collision?

DH: We can

MM: Should throw?

DH: Not strictly, but a possibility.

AWB: function vs. cost

ARB: strongly recommend making runtime duplicate check and throwing. (LH seems to agree? Or just acknowledge?)

link Optional Feature: Class-scoped name declarations

  • Allow name/private declarations to occur as a class body element
  • Any such declared At-Name are scoped to the class body.
1
2
3
4
5
6
7
8
9
class Point {
private @x, @y; // <=== scoped to class body
constructor(x, y) {
this.@x = x;
this.@y = y;
}
get x() { return this.@x; }
get y() { return this.@y; }
}

DH/RW: Makes sense for declaration to see it at once.

LH: Want to be cautious about what we commit to forever.

RW: Fully support this.

LH: Let's work towards understanding the entire commitment

...Discussion about path forward and whether it's too late.

DH: This does resolve an issue that stands out about max min classes: private name props cannot be added declaratively

WH: classes are not worth it without this

BE/LH/RW: Disagree. Classes already support themselves.

YK: Saying that it's too late is not a valuable argument.

DH: Just the API won't be worse. Allen's biggest point is that you cannot use Symbol in declarative forms with super().

DH: (rebuked)

AWB: There is a big hole in classes where super() is allowed only within class, means that name/symbol cannot be used with super()

DH: imperative API is safe to start, At-Names are good, but we don't need them now.

WH: You could say the same about super() in class

DH: No. We have solid, reasonable semantics for where to allow super() and where to error.

LH: I don't think we're ready to design this syntax.

AR: Are we converging on this as an idea that needs solving? Just not now?

MM: If we decided that we had consensus today, we could improve it over the next year.

RW: (agrees)

MM: However, it is late and the agreement of max min was to commit to something light weight that can be built on.

BE: I agree, but I dont think we should disallow exceptions to that cut off date.

LH: syntax was not on the table at the cut off

BE: Firm disagreement.

RW: This is actually a good example of why max min classes is a good idea. It's already an identified addition that creates a massive improvement.

WH: This actually adds the missing piece for me to support classes.

LH: I want something more minimal.

BE: Can we accept it for work, bet on it until at least the next meaning?

EA: Nice that it allows class private as well as instance private

LH: Agrees. If we're going to do this, we have to do all of it. The part that is listed as "optional" actually needs to be included.

AWB: Essential functionality is base declarations at the block level.

I have an ES.next (not 6) solution for "protected".

LH/DH: The baseline is private declaration in statement, classes, object literals. Build from there. As well as whatever the "public" version. BOTH are part of the baseline. NO PROTECTED.

AWB/WH/BE: Yes, I agree.

DH/BE: Move protected to a new strawman.

link Conclusion/Resolution

Consensus on:

  • Need private binding, including: statement form, import and export.
  • Need private prefix form on class methods on object literal props and methods
  • "public" in addition to private, but need to choose keyword
  • dot notation, expression form

Deferred to separate proposal:

  • "Protected"

link Renaming Name to Symbol

(Presented by Dave Herman, Mozilla)

YK: A little nervous that not identical to Lisp

DH: Gave blessing ;) the only diff is that you can't go from string -> symbol, whereas in lisp you can

YK: ok with that.

link Conclusion/Resolution

  • we agree that names are now called symbols (Name => Symbol)
  • new alternatives for syntax to bind a "Unique Symbol" will be a keyword, one of: public, unique, or symbol ie. public @foo; vs symbol @foo; vs unique @foo;

link Early Errors That Possibly Should Not Be

(Presented by Luke Hoban, Microsoft)

LH: Concerns about detecting assignment to constants. Want to just parse, not build name environments, parse trees, etc.

WH: What about detecting a continue to a nonexistent label? That requires name environments.

LH: It's rare enough that it doesn't matter.

WH: Just what are we talking about? Should the assignment 3 = 1 no longer be an early error?

[Debate, without resolution]

[Discussion about whether the ES5.1 early errors should no longer be early errors.] Consensus: No.

[Discussion about when these kinds of errors should be detected. One option mentioned was at function call time at the granularity of a function.]

WH: That's not useful. With arrow functions we'll have many lightweight functions, so the hybrid of early and late checking at function granularity does not do a good job of either early error detection or fully dynamic binding (late error detection).

DH: Not detecting typo'd free variables would be a big loss for one of the motivations for modules.

[Discussions about alternative of having early error detection of things like typo'd variables only in development tools]

WH: Concerned that these will diverge into a mess of incompatible "even-stricter" modes.

DH: macros need to expand at compile-time; we'd essentially be making static features like macros impossible

[Macros require compile time expansion]

BE: we can do the delayed errors now, and modules that use macros could be eagerly compiled; IOW we can make this decision now without necessarily closing that door

LH: need for delaying compilation of cold code is huge; large portions of web workloads consist of cold code

BE: (explains that interns and researchers at Mozilla are working on parsers that can support macros)

DH: Explains sweet.js (similar to coffeescript transcompilation)

DH/BE: Continue research of macros, offline.

MM: List all early errors and discuss the merits

AWB: Are we ok with a class of errors that are reported on each function entry? Static function analysis will simplify certain runtime semantics.

...Will allay performance issues discovered through Chakra and v8 prototyping.

Discussion of label analysis

Strict mode implementation

link Conclusion/Resolution

  • es-discuss will get a list of all early errors that should not be

link Performance Costs of Temporal Dead Zone

(Presented by Luke Hoban, Microsoft)

https://mail.mozilla.org/pipermail/es-discuss/2012-September/024993.html

LH: (introduces discussion)

ARB: Have you tested with let and no temporal dead zone

BE: early-boyer is likely not an accurate test for let. There are closures that capture deep chains of activations. If let is top level, why would it have changed?

LH: We suspect that a majority of the overhead was caused by the read barrier created by temporal dead zones.

...Will continue with testing and gather evidence.

MM/STH/BE: early-boyer is probably innappropriate.

LH: Believe that the motivation of temporal dead zones is not actually a common enough issue in real world code

BE: (proxy for Oliver Hunt) says the whole JSC team is against temporal dead zones on let, support it on const

LH: meta concern is that cases are adding up against let. If the perceived cost is real, measurable performance cost, there will be less buy in from developers.

WH: [as previously mentioned by Brendan], having a lot more scopes to close over (i.e. creating a new one for each loop iteration, etc.) is likely to be the main performance cost of let. What if let is slower merely due to having many more scopes?

BE: (history of let in SpiderMonkey...) No outcry that performance is an issue

MM: (countering the "not common enough" argument) Presented personal experiences where dead zones were essential in detecting problems.

link Conclusion/Resolution

  • No change to temporal dead zone (yet)
  • Get more data, report back

link Global Scope Revisit

YK: Still not in agreement with discussion yesterday, but not blocking the

BE: Recap the problem that revealed the issue.

LH: Can we talk about let/var at the top level?

Current proposal... let would shadow var

ARB: Why?

BE: Global contour in which let binds

AWB: The rule in functions is that you cannot have a var and function of the same name.

MM: is the interaction with the global the same as a "with" scope object.

LH:

YK: class followed by class with the same name: error var followed by let with same identifier name: error

BE: It happens all the time...

1
2
3
for (var i = 0; ...) {}
for (var i = 0; ...) {}

...Not the issue, but this:

1
2
3
4
5
var i;
for (i = 0; ...) {}
var i;
for (i = 0; ...) {}

...is a problem if let throws when name collision occurs.

DH: A serious issue exists... the single global object. It's beginning to feel like we're adding to the issue.

WH: The complexity is not on the number of scopes, but what they do. I'm concerned about the complexity of reflecting let, const, @names, etc. onto a global object.

WH: Also don't want random HTML attributes elsewhere on the page to knock out global let/const/etc. bindings.

AWB: No one has discussed... Any script tag, whose order can be determined... bring deferred scripts to the last script

BE:

1
2
3
4
5
6
7
8
9
10
11
A <script>
B <script> document.write("D <script>")
C <script>
( G ) <
^ ( D )
( A )
^
( B ) <-?
^
( C ) <-?

Hell.

DH: Note that multiple globals is not the problem. The problem is that the one global scope is the "window"

ARB: Implemented global lexical scope, give the impression of one, but is a scope chain.

DH: Why is it any different then having a global that isn't the window?

LH: It has to be.

BE: Points out in chart above that a function in A that refers to a let x = 1; in C, will create an error.

DH: Users make recursive dependencies that they don't realize.

ARB: The way I understood let... we resolve every variable at compile time, (I missed the next part, ARB: Can you fill this in?)

YK: (whiteboard)

1
2
3
4
5
6
7
8
9
10
11
12
<script>
function animate() {
requestAnimationFrame();
}
</script>
<script>
let requestAnimationFrame;
if ( typeof requestAnimationFrame === "undefined" ) {
requestAnimationFrame = ...polyfill.
}
animate();
</script>

BE: Recapping the Window.prototype issue

RW: There is no reason to put everything on the Window.prototype. Object APIs should be own properties of the Global object ("window" in the browser case). This doesn't mean that the needs of EventTarget specification cannot be met by using the Window.prototype. The WebIDL change to move all APIs to a different semantic "space" without understanding the consequences is the worst negligence.

...More discussion...

BE: If we make let, const, class, module, function, var (all binding forms, now and in the future) are global—will this be blocked?

...Discussion...

DH: Hard to decide if a dead zone exists for let on the global object.

ARB:

LH: What are the mechanics of let accessors on the global?

...Discussion about the

Two models to consider:

Andreas: When you have a let binding, it reflected observably as a getter/setter pair with some form of identification as a let binding.

Luke: I can't figure out what the semantics you're describing is

DH: I think it's simple: every let binding is simply stored in a getter/setter pair

ARB: better to think of as a separate scope contour, where the getter/setter accesses it

DH: no difference

ARB: No, it is the difference between being stored inside the object vs inside the separate scope contour

DH: I still don't see the difference

WH: How are the proposed hidden attributes (such as the aforementioned identification of a binding as a 'let' binding) reflected if the global object is a Proxy?

DH: Tom has spec'ed these to "pass through"

BE: Object to the idea that there is an observable getter/setter on let bindings.

ARB: If you don't do it this way, you can't have a temporal dead zone in the global scope.

DH: (to BE) Can you recap your objection to getter/setter pairs on let bindings? Optimization doesn't seem like a long term motivation if we're moving to module

BE/DH/ARB...

Like modules, need to have global getter/setter pairs on let/const bindings

Unless there is a lexical scope or hidden data store...

LH: Observability?

ARB: It would be actually observable if the global object was a Proxy. Think of this in terms of a lexical contour

LH (recapping one of the alternative models)

There are two scopes: Global Object and Global Lexical Scope... when a let binding occurs, there are two things created, one on the Global Object and Global Lexical Scope.

[people generally felt it was easier to comprehend the data living in the scope contour]

link Conclusion/Resolution

Agreed on the AWB/MM/WH alternative model (new binding forms)

  • Allen's 1 extra global scope contourc
  • Redeclaration is an error
  • Shadows all properties on the Global object
  • Does not create a Global property

link Test 262

(Presented by Istvan Sebastian, ECMA)

IS: Someone needs to update the site with the latest version of the test suite in zip file format.

LH/RW/AWB: Needs to be an automated process, if that's possible within the scope of ECMA's policies.

IS: Needs archival snapshots. The standards body is still a classic style standards organization that needs to abide its rules and policies.

link Conclusion/Resolution

Bill Ticehurst to produce recommendation for the automated archival of test 262 at arbitrary states, as needed. Rick Waldron volunteers to assist as necessary.

link Create Archival Utility for ECMA Wiki

2012-10-31: wget -r -l 0 http://wiki.ecmascript.org/

link Conclusion/Resolution

Rick Waldron will champion this

Ecma/TC39 Meeting – Sep 18 2012

link September 18 2012 Meeting Notes

Rick Hudson (RH), John Neumann (JN), Mark Miller (MM), Norbert Lindenberg (NL), Nebojsa Ciric (NC), Allen Wirfs-Brock (AWB), Istvan Sebastian (IS), Luke Hoban (LH), Paul Leathers (PB), Sam Tobin-Hochstadt (STH), Andreas Rossberg (ARB), Brendan Eich (BE), Erik Arvidsson (EA), Dave Herman (DH), Yehuda Katz (YK), Rick Waldron (RW), Eric Ferraiuolo (EF), Matt Sweeney (MS), Doug Crockford (DC)

Introductions. Brief Agenda tweaks

RW: Confirm that Internationalization spec is available, per last meeting

NL: Internationalization specs are available on the Wiki

AWB: Start with Internationalization

IS: We need two products: The spec and a technical report (via test suite)

JN: Would like Internationalization tests to be included with test262

AWB: Finalize by June

link Internationalization

(Presented by Norbert Lindenberg, Mozilla)

Slides

link Review and Approve Final Draft of Internationalization API Specification

(Introduction)

NL: Final draft following major discussion in May and tweaks from July.

Primary change is to Require Normalization By Default

DH: Is this a performance issue? Should we leave it to the lib authors

AWB: Why do we assume lib authors will write wrappers.

YK: Because we have no evidence to the contrary

LH: That implies a judgement about design...

RW: Spec APIs are not bad, they often require simplification for wide acceptance and use.

Discussion returns to whether or not Normalization is required by the specification or if it is implementation independant.

Agreement that generally there should be no "optional" implementation details. Conformance should be explicitly normative.

NL: Note about ES5 assumptions that a string has been normalized before parsed.

NL: Three options to support or ignore:

  1. Normalization
  2. Lowercase to Uppercase first
  3. Numeric sorting

link Don't Use Year 0 in Date/Time Formatting

2 AD, 1 AD, 1 BC, 2 BC

Discussion and explanation

YK: Ruby has a year 0

AWB: Fundamentally Date/Time objects are ms mapped to some external designator, would there be any impact?

Decision: Date calculations will remain as is; but dates before 1AD will be adjusted in localized formatting (Date.prototype.toLocaleString, Intl.DateTimeFormat.prototype.format) to reflect no year 0.

link Conformance Tests

NL: 137 tests, reaches almost all algorithms, coverage is still thin, draft test report

LH: These have been effective in identifying bugs in Chakra prototype implementation

link Implementor's Report

(Google) NC: Chrome/v8 has Intl namespace and the implementation is working towards passing the conformance tests with ~20 failures. Some tests not yet implemented. Google internal use

AWB: What is the feedback?

NC: Mostly migration based discussion for the time being. There was a previously a [Localization] API.

AWB: Issues with name conflict? Wouldn't know if it was prefixed.

NC: Will be removing the prefix

DH/YK/STH: Discussion about globals, as they apply to the future with modules. import foo from ... will reduce naming conflict overall.

(Microsoft) LH: Currently passing 100/137 of conformance tests. Dont have direct user feedback. No one is actively using the prototype.

RW: Is there any communication between implementors?

NC/LH: Only via es-discuss

(Mozilla) NL: Prototyped in SpiderMonkey. Uses ICU for comparison, formatting and feature detection. JS/C++ for implementation, Unicode extensions not yet supported. Passing 128/137.

link Approvals

NL: Final change, move to year 0.

AWB: Need to address the "optional" spec issues.

DH: Not that leaving things unspec is evil, we should just be conservative.

RW: For the sake of clarity there should be a specific list,(via notes?) of "optional" implementation details.

DH: Agree, similar to the history of strict mode list

LH: This can be produced off-line

AWB: In the form of an Annex

DH/LH/AWB: (Discussion about implementation limitations)

Summary Produce Annex that outlines a list of all optional implementation details. Include a rationale for each item that describes strong reasoning for optional implementations.

link Annex

Optional

All Functionality

  • Supported Locales
  • Default Locale
  • Supported subset of unicode
  • Best fit matcher for locales
  • Supported Unicode Extenion values per locale
  • Additional values per conformance clause

Collation

  • Adherence to unicode collaiton algorithm
  • Support for unicode extenions keys kf, kk, kn and parallel options caseFirst, normalization, numeric
  • localized sort orders
  • Default search sensitivity per locale

NumberFormat

  • Support for numbering systems
  • Implementation of non-decimal numbering systems
  • Localized decimal & grouping separators, representation of negative numbers, percent sign
  • Localization grouping
  • Localized concurrency symbols and names

DateTimeFormat

  • Supported data/time formats per locale beyond core set
  • Best fit matcher for formats
  • Supported Calendars
  • Support for numbering systems
  • Localized format patterns, weekday names, month names, era names, am/pm, time zone names

BE: Similar to the underspecified portions of Date

LH: Of course, we'll work together to be as consistent as possible.

link Approval of Intl

JN: If there are no objections, we will forward this document specification, ECMA-402 to the CC & General Assembly for final approval.

...No objection.

JN: With the final modifcations, this document will be submitted to the CC & GA for final approval. NL and NC to produce a list for an Annex of optional details.

JN: Any desire for ISO fast tracking?

(Discussion re: ISO benefits.)

link Conclusion/Resolution

ECMA-402 Approved for submission to ECMA CC & GA

ISO fasttrack postoned (with the limited time frame of 2 months notice prior to presentation the GA, approx Oct 10, 12?)

link Intl 2nd Edition

NL: There is a need to continue work, towards a 2nd edition

JN: Agenda item for Nov.

IS: Need to determine scope and scale of needed changes.

link Conclusion/Resolution

Agenda item for November 2012 to entertain a proposal.

link Parallel JavaScript

(Presented by Rick Hudson, Intel)

link River Trail (Intel)

Slides

Map

  • myArray.map(callback)
  • myArray.map(depth, callback) // for an n-dimensional array
  • elementalFunction (element, index, source)
  • (need slides?)

DH: Not sure that the level of technical detail is yet appropriate (from the perspective of an implementor)

YK: Gratuitous API changes should be avoid

RH: Intentionally avoided using the |thisArg|, think it's complete unnecessary and exists for legacy purpose.

DH: Absolutely not the case and is very important.

RW: For example, when you have a constructor that has properties [[Put]] via map, |thisArg| allows setting the context within the callback to the constructor itself.

DH: This needs to be taken offline, away from the committee.

LH:

Examples of Map

1
2
3
4
5
6
7
8
9
10
11
paArray.map(function(element) {
return element+1;
});
paArray.map(2, function(element) {
return element+1;
});
paArray.map(2, function(element, [i, j], array) {
return element+1;
});

LH/DH: (Discussion of explanation of River Trail semantics and the use cases)

LH: Is it the claim of this proposal to follow the ECMA 262 Semantics.

DH: Yes, up to the issue of floating point non-determinism

LH: Which means an engine cannot detect... (lost)

RH: We do rely on the programmer to know that they need to write an associative and commutative function. Tools can be provided to help.

LH: Worried about implicitly saying that a function does not match what ECMA 262 says it will mean.

DH: (Clarifies that it's just JavaScript)

BE: Parallelization can be painfully slow

YK: If it's straight forward, then why not specify how Parallelization is accomplished

DH/BE: Too early to attempt to specify Parallelization detection.

Lengthy discussion of Parallelization "mode" switching semantics... Devolved. Ended abruptly when no progress was made.

Shape

  • Mixing 1D and 2D operations requires an understanding of shape
  • Shape determined at construction

Identity

  • Accessors to non leaf elements of ParallelArrays will return a fresh ParallelArray
  • References semantics for === remains consistent

Between the two:

  • pa[2] === pa[2] true for only 1D ParallelArrays
  • pa[2] === pa[2] always false when shape is > 1

LH: Asks for explanation...

DH: Will fill in blanks offline

AWB: Are there any other efforts that are developing competing specifications?

RH: Not exactly, but WebCL(Kronos?) is similar in the application they are trying to address.

DH: A different name?

BE: Vector?

DH: Also, the world will hate us for creating a new Array-like.

RW: Only a problem when creating constructors that produce objects with numeric indices and a length property and no Array proto API.

DH: Which it does.

RW: Then it will be a problem.

MM: The proliferation of Array-like things is unfortunate

RW: And ES6 reduces that pain by effectively eliminating arguments via rest and Array.from()

...

DH: There was also the idea of having parallel-specific methods.

Derailed to Array-like API issues on the whole... When to implement array API and when not. Why and why not...

link Conclusion/Resolution

Further research and offline discussion.

link Define Properties Operator ":="

(Presented by Allen Wirfs-Brock, Mozilla)

Introduction, rationale as published: http://wiki.ecmascript.org/doku.php?id=strawman:define_properties_operator

DH/AWB/RW: (discussion) Object.define, Object.put

RW: Have research and supporting cases from jQuery, Dojo, YUI, Node core, Underscore... Always exists an approximation of "merging" or "extending"

AWB: We should strive to fix the future and correct developers thinking about "define" and "assign"

LH: That's a dangerous scenario to put developers in, where they have to think about assignment vs definition.

RW: The newly created dom node case, for batch property assignment (originally brought forth by Doug) is the second most important use-case, but implicit define will pave innerHTML (or any dom node properties)

...

DH: Shouldn't create syntax for the less common operation.

MM: Agreed.

AWB: But there is no way to:

  • Batch define class-side properties
  • Batch define constructor properties
  • Batch define instance properties

YK: Nothing for static properties in classes yet anyway

MM: But not sure we need any syntax yet. If there was a lot of precedent for batch define, in the same way there is for assign/put, then it would make sense, but there is very little userland history for define

RW: Agreed, assign/put is a cow-highway to pave, but user code has barely begun to include regular use of definePropert(y|ies)

MM: (comments about private name access concerns)

AWB:

LH: Long term, we're going to have to consider features that are allowed to move private state.

DH: Essentially, you'd need inside access and list private items.

Discussion about side channel access via newly defined properties that were never expected on the object.

Discussion about the needs of Private Names, Unique Names and WeakMaps.

BE: People want Private Names as much as they want Unique Names

YK: Can we tell people to use Unique Name when they want copyable and Private Name when not.

BE: I thought of this earlier, but wasn't sure, but it could work

AWB: ...

MM: Given ES6, remove the copying of private names, allow copying unique names: Can this be written as library code?

DH/YK/RW: Devs want Object.define which is Object.defineProperties Object.assign() or Object.put() (these are the same, just different names)

Extensive discussion around whether or not Object.define()

Extensive discussion around whether or not Object.assign()

Derailed due to concise method's making non-enumerables, which means they won't copy if the rule disallows copying.

...Revisit "Concise Method Definition" (add anchor)

Object.define( target, source )

  • All own properties of source
  • plain object descriptor map is copied
  • private names are not copied
  • unique names are copied
  • super mechanism (rebind super)

Object.assign( target, source )

  • Only enumerable own properties of source
  • Invoke [[Get]] on property list derived from source, for each property in list [[Put]] on target
  • private names are not copied
  • unique names are copied
  • super mechanism (rebind super)... AWB To determine needs
  • Returns modified "target"

DH, MM, AWB: Object.assign a well worn enough cow-path to be worth paving. Object.define isn't, and so should only be standardized after libraries have explored the space.

link Conclusion/Resolution

Accept Object.assign into ES6, but postpone Object.define (or something like it) to discussion of future versions.

Reference materials and use cases: https://gist.github.com/3744794

(** The inclusion of variable length sources is imperative to match real world patterns found in the most ubiquitous JS libraries)

link Concise Method Definition, Revisited

RW: Defaulting concise methods to non-enumerable is a mistake

DH: Not sure about the decision to go non-enumerable. Users expect that things they create to be enumerable and things that the platform provides to be non-enumerable.

LH: enumerability is not a real concept with any sort of meaning.

EA: (reveals the broken-ness of the DOM)

No longer arguable.

link Conclusion/Resolution

Concise method definitions create [[Enumerable]]: true

link Scoping of the Top Level

link var and the window.prototype issue

var indexedDB = window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.indexedDB;

Issue with WebIDL change.

REVISIT.

link let, const, module, class

Global scope contours

AWB: propose extra global contour, shared across all scripts, for new binding forms, to avoid colliding with Window object

others skeptical of complexity of new scoping model for globals

link Conclusion/Resolution

continued on second day, resolved then

Ecma/TC39 Meeting – Jul 26 2012

link July 26 2012 Meeting Notes

Present: Mark Miller (MM), Brendan Eich (BE), Yehuda Katz (YK), Luke Hoban (LH), Rick Waldron (RW), Alex Russell (AR), Tom Van-Cutsem (TVC), Bill Ticehurst (BT), Sam Tobin-Hochstadt (STH), Allen Wirfs-Brock (AWB), Doug Crockford (DC), John Neumann (JN), Erik Arvidsson (EA), Dave Herman (DH), Norbert Lindenberg (NL), Oliver Hunt (OH)

link Maxmin class semantics

YK: namespacing pattern: class that goes inside existing object; like Ember.View

DH: Ember.View = class ...

AWB: or Ember = { View: class ... }

AWB: early error list

  • naming class eval/arguments
  • duplicate class element names
  • extends expression contains a yield
  • method name constructor used on get, set, or generator

MM: yield should not be an error!

DH: definitely not! burden of proof is on the rejector; there's no reason to reject here

YK: why can't we do a getter?

DH: there's no way to declaratively figure out what the actual function for the class is, because the getter returns the function

AWB: class declarations create const bindings

AR: can you justify?

AWB: why would you want to overwrite it?

RW: what about builtins needing to be patched?

DH: those are independently specified to be writable; the relevant question is whether user programs will want to patch up local class bindings

AWB: whether this is a good idea probably depends on whether you're a library writer or application writer; if you aren't exporting class definitions

AR: you could still say const x = class

YK: that distinction isn't useful; every app has stuff like libraries

AR: restriction needs justification

DC: my preference is only for the expression form so there's no confusion

RW: surveyed ~200 developers, majority did not want const bindings by default

MM: I like crock's suggestion, just don't do the declarative one

EA: what?

LH: that's just putting cost on everyone else rather than us

MM: no, I'm talking about saving the cognitive cost to user

YK: if we went with const by default, I'd agree we shouldn't do declarative

AR: goal is most value for shortest syntax, without footguns; the analogy with const seems tenuous

AWB: this is subtle, and most people won't even notice

DH: I don't buy that there are significant errors being caught, there's no benefit to engines, there's not enough benefit to users, and it's clear there are costs. so I don't see any reason to do const binding by default

general agreement

MM: I'm opposed to declarative form. but if it is going to be declarative, should pick a declarative form and say it's the same as that, and let is the only clear candidate

DH: I'm not convinced function is impossible

MM: the expression extends is the killer. makes it impossible

LH: I'm convinced it can't hoist

DH: why not a more restricted syntax for declarative form in order to get hoisting?

1
2
3
4
{
class Sup extends Object { ... }
class Sub extends Sup { ... }
}

LH: surprising that you can't compute the parent

DH: there are surprises in each alternative we've talked about here; but I claim it's surprising to lose hoisting

OH: relevant analogy here is the fact that other languages with declarative classes don't care about order

LH: CoffeeScript does; it translates to var x = ...

AR: pulse?

DH: I think we all acknowledge this is tricky; I feel strongest that leaving out the declarative is failing in our duty

MM: if we leave out the declarative, then people will simply learn that the language is let c = class

BE: why are we debating this?

STH: Mark and Doug are arguing it

BE: over-minimizing and failing at usability

YK: let x = class extends Bar { } is just crazy

DH: that's laughable as the common case

AWB: this came from the hoisting debate

BE: I thought we agreed to dead zone. if we get stuck on this we'll never finish classes

LH: agreed; we need a separate proposal for hoisting

DH: happy to revisit later if I can come up with better alternatives

MM: we have adequate consensus that declarative desugars to let

AWB: classes are strict?

STH: I thought class did not imply strict mode

AR: does anyone want that?

no

AWB: default constructor has empty body? we'll get back to this

AWB: local class name scoping? similar to named function expression, but const bound?

DH: const bound?

AWB: just like NFE

DH: I actually didn't know NFE's had a const binding!

AWB: is this a bug? should we reconsider?

MM: avoids refactoring hazard

MM: my first choice would be to fix function: within function body its name is const; second choice is for class to be consistent

BE: not sure why we're talking about this, can't be changed

MM: in that case the class expression form should follow NFE

general agreement

DC: I disagree with the scoping decision about class declarations

DH: confused what we're talking about

STH: in body of class declaration, should there be a fresh scope contour

OH: it's not uncommon to overwrite the class

MM: example:

1
2
3
4
5
class Foo {
self() { return Foo }
}
...
new Foo().self() === Foo // can fail

this is very confusing for this to fail

DH: why would you ever want the extra scope contour?

STH: Rick gave a good example:

1
2
3
4
5
6
class C {
m(x) { return x instanceof C }
}
var y = new C;
C = 17
y.m(y)

DH: not compelling; you mutated C! if you need the earlier value, you should save it; the confusion would only arise if you expected C to be a static class like in Java, but that's not how JavaScript bindings work

RW: the common pattern being the defensive-constructor pattern:

1
2
3
4
5
6
function C() {
if (!(this instanceof C)) {
return new C();
}
...
}

DH: now I'm that much more confident that there should not be another scope contour; I don't see any compelling argument

AWB: let me throw up another justification: class declarations often appear at global scope, not uncommon for somebody to write class body where there are references to the class; at global scope, anybody could have assigned to that value

DH: I don't want to poison non-global cases just to protect against one hazard of global code, when global code is hazardous anyway

AWB: I would put protecting global code at a higher priority than a subtlety of inner bindings, but I'll go with the flow if I can't convince you

DC: I don't want to hold this up

MM: are you willing to go with the function parallel?

DC: yes; I don't prefer it but I won't hold this up

AWB: missing extends, what's the default? intrinsics

agreement

AWB: extends null: prototype is null, Foo.[[Prototype]] extends intrinsic Function.prototype

agreement

AWB: extends a constructor:

1
2
3
class Foo extends Object { }
Foo.[[Prototype]]: (Object)
Foo.prototype.[[Prototype]]: (Object).prototype

IOW, class-side inheritance

MM: I disagree, the history of JS does not have it

BE: I disagree with that claim, history shows some examples on both sides

EA: people do refer to this in static functions; they have the freedom to use the class name or this, and they do both

LH: CoffeeScript does class-side inheritance, but they don't do it like this -- they copy

BE: but they will avoid the copy once you implement dunder-proto

MM: you can't depend on it

BE: this gives programmers more flexibility to do it however they want

MM: but then people can't use a this-sensitive function!

BE: not true, the contract of a JS function includes its this-sensitivity

Arv, AR: nod visibly

LH: at end of day, plenty of static functions in JS that are this-sensitive

YK: that's the style of program that I write

EA: some style guides say don't do it

LH: backbone does this

MM: so Foo will inherit Object.create, Object.getOwnPropertyDescriptor, etc?

DH: that does mean we'll be more and more hampered from adding methods to Object

EA: but now we have modules

BE: true, that's the right answer

MM: polluting of statics with everything in Object is fatal; those are just not relevant to most of the class abstractions people write; when I write

1
class Point { }

I don't want Point.getOwnPropertyDescriptor

AWB: you only opt into that with class Point extends Object; with class Point { } you don't get any of that stuff

DH: feels giddy and sees the clouds part and sun shining through, with angels singing from on high

YK: also, there are override hazards of pollution: if someone freezes Object, then you wouldn't be able to override sweet class method names like keys(), so the ability to avoid that pollution is important

MM: valid point. thing is, we don't have static form b/c you can supposedly use imperative assignment, but that won't work for frozen classes

BE: that's just an argument for statics in the future

AWB: minimality ftw

AWB: class Foo extends Object.prototype?

LH: this surprised me when I saw it in the spec

AWB: older version of class proposal had a "prototype" contextual keyword for this case

DH: what happens if you're defining a meta-class? you can't tell whether it's a prototype or a constructor

BE: that's a smell

AWB: constructor trumps object

BE: YAGNI, cut it

AWB: so what do we do if it's not a constructor?

DH: throw

BE: that's more future-proof

general agreement

AWB: extends neither an object nor null: type error

DH: actual type errors in JS, yay!

RW: curious: what if Foo extends { ... }

DH: non-constructable, so error; but could use a function literal

AWB: extends value is constructor but its prototype value is neither an object nor null: type error (existing semantics of new: silently uses Object.prototype)

agreement

AWB: Foo.prototype is an immutable binding? builtin constructors are immutable, user function(){} mutable

some surprise

MM: make .constructor mutable but .prototype immutable

YK: why? (I want mutable)

MM: nice for classes for instanceof to be a reliable test

YK: why?

AWB: classes are higher integrity; association between constructor and prototype actually means something now

BE: I'm moved by higher-integrity, self-hosting with minimal work

STH: not compelling to make self-hosting easy, just possible; defineProperty is just fine for that

DH: most everyone seems to agree that .prototype is immutable, .constructor is mutable. Arv and AR, thoughts?

EA: that's fine

AR: yup, that's fine

AWB: method attributes: sealed? ({ writeable: true, configurable: false, enumerable: false})

  • configurable: false -- you've established a specific shape

YK: you don't want to switch from a data property to an accessor?

AWB: non-configurable but writable is reasonable

MM: this depends crucially on our stance on override mistake; this prevents me from making an accessor

AR: I don't see why we're considering making this anything other than writeable: true, configurable: true

BE: Allen feels having the shape be fixed is useful

discussion

BE: so consensus is writable: true, configurable: true

agreement

AWB: methods are not constructable?

DH: what?

MM: biggest benefit: this further aligns classes with builtins

MM: three reasons for this:

  1. precedent in builtins
  2. using a method as a constructor is generally nonsense
  3. to freeze a class, I have to freeze the .prototype of the methods on the prototype!!

LH: compelling for me: never seen a class-like abstraction on a prototype of a class-like abstraction

MM: I have, but you still can; just do it in a way that's obvious, don't do it with method syntax

BE: hard cases make bad law! (agreeing with MM -- use a longhand)

YK: so you can say classes really only existed as builtins, now they're expressible

AWB: get/set accessors are constructors? that's just the way they are in ES5

BE: is there precedent in builtins?

AWB: nothing explicit

YK: I'd prefer consistency between these last two cases

AWB: accessor properties on prototype are enumerable

BE: what about DOM/WebIDL? accessors on prototype?

LH: they're enumerable, yes

AWB: suggestion: concise methods should be the same for both classes and object literals

  • strictness
  • enumerability
  • constructability
  • attributes

AWB: breaking change from ES5: get/set functions non-constructable

AWB: class accessor properties:

  • enumerable: false, configurable: false

AR: no

EA: no

YK: when you use an accessor you're trying to act like a data property

BE: so compelling argument is: accessors are enumerable, configurable, and writable

AWB: Luke suggests that default constructor should do a super-constructor call with same arguments constructor(...args) {super(...args)}

BE: default constructor in CoffeeScript, Ruby

AWB: perhaps needs to test for Object constructor and not call it

DH: no observable difference!

MM: if there's no observable difference, go with simplest spec

AWB: other places where we do implicit super call? I say no

DH: I say no.

LH: I agree, I think there's no clear way for us to do it, but I also think there will be many, many bugs

BE: irreducible complexity here, caveat refactorer

link getPrototypeOf trap

TVC: (introduction)

__proto__ writable destroys invariant that [[Prototype]] link is stable

Frozen objects should continue to have stable prototype chain

getPrototypeOf trap result should be consistent wth target object's proto

MM: if the proto can be changed, the proxy should...?

TVC: spec interceptable [[Prototype]]

[[Prototype]] is currently an internal prop

Would need to become internal accessor prop or split into [[GetProto]] / [[SetProto]]

[[GetProto]] / [[SetProto]] would trigger traps for proxies

AWB/BE: This is good

YK: Do we want an analogous setPrototypeOf trap?

TVC: Yes

AWB: If you have capability to set prototype ?

TVC: proxy.__proto__ should just trigger the proxy's get trap

1
2
3
4
var p = Proxy(target, handler)
p.__proto__ // => handler.get(target, "__proto__", p)
p.__proto__ = x // => handler.set(target, "__proto__", x, p)

...

Trapping instanceof

Function [[HasInstance]]

x instanceof Global answering true if x and Global live in separate frames/windows

1
2
3
var fp = Proxy(targetFunction, handler);
x instanceof fp // handler.hasInstance(targetFunction, x)

MM: Explains concerns originally raised on es-discuss list by David Bruant, but shows the cap-leak is tolerable ...

DH: if hasInstance private name on instanceof RHS...

MM: What Object.prototype does private name inherit from?

AWB: Probably null

BE: the E4X any (*) name had null proto in SpiderMonkey, was true singleton in VM

AWB: functions have home context, but no reason for objects to

DH: this is a new idea of value that is not really any object

OH: if it has no properties and no prototype

BE: cannot be forged.

Discussion about unforgeability.

DH: Trapping instanceof use case

Trapping Object.isExtensible

Currently Object.isExtensible doesnt trap same for isSealed isFrozen

1
2
3
var p = Proxy(target, handler)
Object.isExtensible( p ) => Object.isExtensible

Direct Proxies: "internal" properties

Issue raised by Jason Orendorff; auto unwrapping is dangerous if built-in methods return non-primitive values

Case:

1
2
3
4
5
6
var arr = [o1, o2, o3];
var it = arr.iterator();
var membraneP = wrap(it);
it.next.call(membraneP)

Solution (?)

Instead of auto-unwrapping, delegate to a nativeCall trap (which auto-unwraps by default)

[[PrimitiveValue]]

BE: nativeCall trap is back door between built-in this-type-specific method impls and proxies. Not good for standardization. Better to make such built-ins generic via Name object internal property identifiers, a la AWB's subclassing built-ins strawman

Discussion moved to Subclassing...

MM: re: what you want syntax wise

AWB: one way to address, not use instance that is automattically created, create new array and patch the proto

... BE: (back to nativeCall trap)

AWB: Let's continue the issue of subclassability on es-discuss

TVC: defaultValue slide

See slide?

BE/AWB: defer this to reflect spec handling, non-observable way.

link Proxies and private names

TVC: getName(target, name.public) instead of get(target, name.public) -- this way get trap that doesn't expect name objects won't break on unexpected inputs

DH: has, delete, ...? bigger surface area

TVC: you'd still have to branch in the code, so this is cleaner for user

YK: debugging tool will want to be able to see these things

OH: a built-in debugger will have hooks into the VM

YK: many debuggers use reflection

BE: so it's just a matter of having a bunch of XXXName traps. in for a penny, in for a pound

STH: this is simple and straightforward, we know how to do it

BE: when in doubt use brute force (K. Thompson)

STH: when brute force doesn't work, you're not using enough of it

TVC: if getName returns undefined, forwards to target; so default behavior is transparent proxying

TVC: otherwise, getName takes public name and returns [privateName, value] to show that you know the private name and produce the value

STH: what about set?

TVC: returns name and success value

DH: what about unique names?

TVC: same mechanism

DH: so name.public === name?

MM: I like that

MM: are unique names in?

DH: I think so

BE: are they actually distinguishable?

MM: have to be if name.public === name or name.public !== name distinction

DH: (named) boolean flag to Name constructor

DH: do we have some way of reflecting unique names?

TVC: Object.getNames() ?

DH: ugh...

AWB: maybe a flag to Object.getOwnPropertyNames({ unique: true })

BE (editing notes): flags to methods are an API design anti-pattern

TVC: VirtualHandler fundamental traps throw, should they forward instead?

agreement

TVC: and rename to Handler?

agreement

MM: next issue: freeze, seal, defineOwnProperties each modify configuration of bunches of separate properties, and can fail partway through; we tried & failed in ES5 to make it atomic

MM: current unspecified order means could break

MM: tom did something in his code that's beautiful: order-independent. just keep going, remember you failed, do as many as you can, and then throw at the end

STH: if target is proxy, weird unpredictably stuff can happen

DH: no worse than anything that does for-in loops, right?

TVC: well, it's getOwnPropertyNames

MM: that's specified to for-in order, right?

DH: but what does for-in order say about non-enumerable properties? evil grin

MM: cracks up

AWB: sounds like an ES5 bug!

link VirtualHandler

VirtualHandler Rename VirtualHandler to just Handler?

Tom Van-Cutsem's Proxy presentation slides:

http://soft.vub.ac.be/~tvcutsem/invokedynamic/presentations/TC39-Proxies-July2012.pdf

link Template strings

(http://wiki.ecmascript.org/doku.php?id=harmony:quasis)

AWB: first order of business, to ban the term "quasis"

applause

AWB: proposing "string templates" (note: settled on Template Strings ^RW)

DH: a lot of people say "string interpolation" in other languages

AWB: must use ${identifier}, don't allow $identifier

EA: uncomfortable with that

BE: troublesome to identify right end of identifier

EA: withdraw my objection

AWB: untagged quasi is PrimaryExpression, tagged quasi is CallExpression

AWB: at runtime, tag must evaluate to a function

DH: well, you just do a call and that does the check

AWB: lexing treated similarly to regexp; add a new context called "lexical goal" so lexer can tell what a curly means (like a flex(1) mode)

AWB: default escaping should be equivalent to normal strings

BE: we should canonicalize line separators to \n

AWB: for both cooked and raw?

BE: raw should be raw!

AWB: raw tag is a property of the String constructor:

1
String.raw`In Javascript '\n' is a line-feed.`

DH: that's pretty badass

BE: too long a name; wanna import a small name from a module

AWB: well, importing takes more characters than renaming with a var declaration

BE: let's put off the bikeshed in the interest of time

AWB: simplify call site object (first arg to prefix-tag function): it's just an array of the cooked elements since that's the common case, with a .raw expando holding array of the raw elements, both arrays frozen

BE: is there a grawlix problem with ` syntax?

DH: I've tried polling and opinions are utterly mutually incompatible

BE: what about mandated prefix but with existing e.g. ' or " quotes

LH: that's just wrong, the most common case will be unprefixed

MM: proposal for object literals inside ${...} context, based on object literal shorthand {foo} meaning not {foo:foo} but rather {get foo() foo, set foo(bar) {foo=bar}} to sync variable foo with property (!)

STH: that is going to be utterly unexpected

MM: ok, not gonna argue for it

AWB: what's left on the agenda?

RW: Erik is gonna take another whack at the error stack proposal

link Map and Set methods: conclusion

BE: forEach on maps and sets -- how about common signature, set passes e as index:

1
2
3
array a.forEach((e, i, a) => ~~~)
map m.forEach((v, k, m) => ~~~)
set s.forEach((e, e, s) => ~~~)

FILED: https://bugs.ecmascript.org/show_bug.cgi?id=591 FILED: https://bugs.ecmascript.org/show_bug.cgi?id=592

link Wiki

DH: I'd love help with a documentation hack day for the wiki

link Scoping for C-style loops

LH: another agenda item we skipped: for (let ; ; ) binding semantics

DH: I thought we came to agreement on that at the Yahoo! meeting?

AWB: we had a long discussion and consensus was to make for (let ; ;) bind on each iteration

AWB: subsequent to that, considerable discussion on es-discuss about that, issues associated with closure capture occurring in the initialization expressions; couple different semantics to work around that, with more complex copying at each iteration; another approach is a new kind of Reference value, got really complex

AWB: working on the specs, I took easy way out for now; defined it a la C# (per-loop lexical binding); just for now b/c it's simple, understandable, and there's still controversy

AWB: another option is not to have a let for of C-style loops

STH, DH, OH: no!!!

DH: this needs another trip around the block but no time today

MM: my opinion is it doesn't matter what happens with closure capture in the head, b/c it's an esoteric case that will be extremely rare

BE: I think the January semantics is still probably the right answer:

1
2
3
4
5
6
var g;
for (let f = () => f; ; ) {
g = f;
break;
}
g(); // returns () => f

OH: it logically makes sense

Ecma/TC39 Meeting – Jul 25 2012

link July 25 2012 Meeting Notes

Present: Mark Miller (MM), Brendan Eich (BE), Yehuda Katz (YK), Luke Hoban (LH), Andreas Rossberg (ARB), Rick Waldron (RW), Alex Russell (AR), Tom Van-Cutsem (TVC), Bill Ticehurst (BT), Rafeal Weinstein (RWS), Sam Tobin-Hochstadt (STH), Allen Wirfs-Brock (AWB), Doug Crockford (DC), John Neumann (JN), Erik Arvidsson (EA), Dave Herman (DH), Norbert Lindenberg (NL), Oliver Hunt (OH)

link Scoping Rules for Global Lexical Declaration

AWB:

  1. Global scoping var vs. let and const declarations var and function need to go on global object

  2. What do we do with new binding forms? (class, module, imports, let, const) Q. Should these become properties of the global object?

DH: Not sure a restriction is needed, the global scope is the global object in JavaScript. With modules, globals are less of a problem.

YK: (clarification)

AWB, DH, BE: (providing background, e.g. on temporal dead zone for let/const/classs

BE: Agree there needs to be some form of additional info not in property descriptor

ARB: Need additional static scope information e.g. for modules. Need additional dynamic information for temporal deadzone.

DH: If you drop the idea that let is always let everywhere. Questions whether let should be more like var at global scope.

ARB: Does not work for modules.

AR: Reasonable to say that the global scope is never finished and that properties can continue to be defined

AWB: An example.

A const declaration; it creates a property on the global object; it's not defined yet; Before it's initialized another piece of code sets the value - what happens?

DH: (board notes)

  1. 2 Contours, Nested "REPL"

  • var, function go in global
  • let, const, module, class... all get modeled lexically as usual in inner contour
  • each script's inner contour is embedded in previous script's inner contour
  1. 2 Contours, Not Nested "Uniform Let"

  • var, function, go in global
  • let, const, module, class... all get modeled lexically as usual in inner contour
  • each script's inner contour is "private" to that script
  1. 1 Contour, Global "Traditional"

  • var, function, let, const, module, class... everything is a property of the global object.
  • Additional scope refs in a side table of global, shared across scripts
  • each script updates the side table
  1. 2 Contours, Not Nested - Merged "Expando"

  • var, function, go in global
  • let, const, module, class... all lexical
  • each script updates lexical contour of previous scripts

AWB: "Expando" was previously agreed upon, where the additional layer of lexical scope is available but shared. (Notes that Andreas did not buy into this)

DH: Agrees. Explains where "Expando" fixes the problems of "Traditional".

1
2
3
4
5
6
|---------|
| get x |
| set x |
| |---------|
| | x: let |
|-----|---------|

This would identify that "x" was declared with "let" and so forth.

STH:


A.

1
2
3
4
5
6
<s>
let x;
</s>
<s>
var x;
</s>

"Expando" (#4) Makes this an error


link B.

1
2
3
4
<s>
let x = 1;
window.x;
</s>

Ecma/TC39 Meeting – Jul 24 2012

link July 24 2012 Meeting Notes

Present: Yehuda Katz (YK), Luke Hoban (LH), Rick Waldron (RW), Alex Russell (AR), Tom Van Cutsem (TVC), Bill Ticehurst (BT), Brendan Eich (BE), Sam Tobin-Hochstadt (STH), Norbert Lindenberg (NL), Allen Wirfs-Brock (AWB), Doug Crockford (DC), John Neumann (JN), Oliver Hunt (OH), Erik Arvidsson (EA), Dave Herman (DH)

10:00-11:00am

Discussion of proposed agenda.

Determine participants required for specific subjects.

July agenda adopted

May minutes approved

link 4.1 AWB Presents changes resulting in latest drafts

Draft related bug filing Increased community participation, a good thing Issue with numbers not matching duplicate filings, be aware

Quasi Literal added to specification Spec issues have arisen, will review

Initial work defining tail call semantics (still need to define tail positions in 13.7) What defines a "tail call" in ES Existing Call forms need to be specified in how they relate to tail positions. (call, apply, etc)

STH: Important that call and apply be treated as tail calls

YK: and accessors

STH: Agree.

...discussion of examples

AWB: Differences between accessor calls as they apply to proxy call traps, not definitively identifiable at syntax level. The function call operator and the call trap.

TVC: Proxy trap calls currently can never be in a tail position (except "apply" and "construct" traps)

STH: call should be in tail position. Clarification of known call site syntax, per spec.

link Consensus/Resolution

Anything that could invoke user written code in a tail position to act as a tail call.

call, apply, accessors, quasi (interpolation), proxy calls

We still need to specify the tail positions in the syntax. There's a start by DH on http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls which uses an attribute grammar, but the current spec draft leaves this blank.

Filed: https://bugs.ecmascript.org/show_bug.cgi?id=590

link 4.5 RegEx "Web Reality"

(http://wiki.ecmascript.org/doku.php?id=strawman:match_web_reality_spec)

Introduction to discussion by Luke Hoban

LH: Attempted to write a guide to make regex specification match current implementation wherein order of production matters. See 15.10.1 Patterns in above link.

...Gives specfic examples from 15.10.1

Discussion between AWB and LH re: semantic annotations and redefinition.

YK: Do non-web implementations match current spec or web reality?

AR: Are there any non-web implementations?

YK: Rhino?

BE: matches reality because based on SpiderMonkey circa 1998

Test cases? Yes.

BT: Yes, cases exist in Chakra

LH: (Refers to examples)

NL: Do these affect unicode? We had agreement at previous meeting that web reality changes would not be applied in Unicode mode (/re/u).

LH: This is what regex is in reality... Waldemar did not want to specify because it's too hard to specify, but now the work is done

AWB: Too hard is not an excuse to not specify, good that the work is now done.

Discussion of "\u" in existing regex - \ug or \u{12} is interpreted, but differently than planned for Unicode mode

Trailing /u flag?

Makes grammar more complicated to have \u{...} only if /u flag used.

AWB: Three things to address: Web reality, Unicode support, new extensions

LH: /u the only way to opt-in to Unicode escapes with curlies, with Unicode extensions.

NL: need to reserve backslash with character for new escapes in the future, e.g. \p for Unicode character properties

OH: Fairly substantial regex in wild all created with RegExp constructor.

YK: Moving forward: Evangelize using Unicode and tacking "/u" onto all new regex?

BE, OH, AR: yes.

Decision: LH and NL to collaborate on integrated proposal

link 4.7 Adding forEach to Map and Set

http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets

Deferred, got to it on third day

link 4.9 getClassNameOf

BE: Recap, last meeting there was discussion about getting a strawman from YK

YK: I began specifying, but existing questions prevented

BE: some want to solve not only the typeof null problem, but also "array"

YK: What is the usecase for Object.isObject

DC: Polymorphic interface

AWB: "has properties"

RW: Similar to isNaN: isNull that is only for null

OH:(Reiterates that we cannot change typeof)

AWB: what is it about host (exotic) objects that need to be differentiated from native (ordinary) objects?

YK: Reclarification about things that are not objects (in the [object Object] sense) that say they are.

AWB: If we go down this path, can anyone redefine the return value

YK: My question is: either always return object Object, or let anyone change to return anything

AWB: Rephrase as "extending toString()". Removing [[Class]] from spec, but now as [[NativeBrand]]. The default: exactly as they are today. in ES6, if this property is defined, then use it, if not, use default.

Mixed discussion of real world uses of: Object.prototype.toString.call(o)

BE: 1JS Killed typeof null

BE, OH: Like the idea of a configurable property to define explicit value of brand

YK: why is what "toString" returns so important?

AR: 2 things:

  1. Fixing is not easy
  2. How to correctly fix w/o making more surface area for the wrong thing

link Consensus/Resolution

There is worry that changes to spec that affect the return of toString will have adverse impact on existing libraries and users when they encounter new runtime behaviours where the existing behaviour is expected.

Belief that we need a more flexible mechanism, whether it is AWB's configurable property that defaults when not explicitly set, or AR et al trait type test proposal.

BE, AWB: nominal type tests considered an anti-pattern per Smalltalk, but they happen in JS not only "because they can" -- sometimes because of built-ins you need to know

link 6 Internationalization Standard

Norbert Lindenberg: (Introduction and opening discussion)

Discussion, re: contributors

link 6.1 Last call for feedback before final draft

Function length values? Using ES5 section 15 rules would cause respecified functions like String.prototype.localeCompare to have larger length values; using ES6 rules would let them keep old values.

Leads into larger discussion about Function length property.

Decision: Apply ES6 rules to all functions in Internationalization API.

Numbering system, number formatting system. Would like to reference Unicode Technical Standard 35.

Outstanding issue:

If you have 4 different impls, 3 of them support a language that you want to support, how can you polyfill the 4th to support the language.

The constructor can re-declared?

link Conclusion/Resolution

There is no easy way currently, second version of Intl spec will address this.

Conformance tests being written for test262.

NL will have the final draft prepared for September meeting, but will produce drafts leading up to that meeting.

link 6.2 Microsoft and Google are implementing prototypes

link Unicode support

AWB:

within curlies: any unicode code point value \u{nnn} so essentially three ways within string literal:

  • two old-style escapes, expressing utf16 encoding
  • two new-style escapes, expressing utf16 encoding
  • one new-style escape, expressing code point

BT: treating curlies as utf32 value? AWB: curlies contain code point value, which you could call utf32

DH: old-style escapes always are a single utf16 code unit, so always .length 1; new-style escapes always are a single Unicode code point, so may have .length 2

NL: "<>" = "\u{1F601}" = "\uD83D\uDE01" = "\u{D83D}\u{DE01}"

AWB: one point of controversy: what happens with utf16 escape sequences within identifiers

  • no current impl recognizes suppl pair escape sequences for suppl identifier characters
  • var <<wacky identifier>> = 12 -- is that a valid identifier?
  • var \u{<<wacky identifier code point>>} = 12 -- is that a valid identifier?

NL: and, for example, what if it goes in an eval?

DH: careful! difference between:

1
2
3
eval("var <<emoji>> = 6")
eval("var \uD83D\uDE01 = 6")
eval("var \\uD83D\\uDE01 = 6")

AWB: disallowed:

var \uD83D\uDE01 = 6 eval("var \\uD83D\\uDE01 = 6")

allowed:

var \u{1F601} = 6 eval("var \\u{1F601} = 6")

DH: any reason to allow those?

YK: sometimes tools taking Unicode identifiers from other languages and translating to JS

DC: we have an opportunity to do this right; \u{...} is the right way to think of things

DH: we have eval in the language, so the language thinks of strings as UTF16 and should have a correspondence in the concept of programs

LH: there's just no strong argument for this inconsistency

DH: there's no real practical value for disallowing; there is potential harm for the inconsistency in causing confusion in an already-complicated space

DC: the only real value here is for attackers; no normal code uses this

BE: and maybe code generators

LH: it's just removing an inconsistency that could be a gotcha

LH: there isn't a codePointLength -- is that intentional?

AWB: since strings are immutable could be precomputed

DH: which is why you want it to be provided by the engine, so it can optimize (precompute, cache, whatever)

DH: should it be a function, to signal to programmer that it has a potential cost?

AR: but no other length is a function

DH: fair enough, just spitballing

AWB: what about code point iteration from end to beginning? and also codePointIndexOf? don't have those yet

link 4.1 (cont) Processing full Unicode Source Code

String Value

Conversion of the input program to code point sequence outside of standard

Trad. \uxxxx escapes represent a single char, creates a single BMP character, 16bit element

Issue: in string values, ?? (Etherpad is broken) === \u1F601 === \uD83D\uDE01 === \u{D83D}\u{DE01}. In identifiers, ?? === \u1F601 !== \uD83D\uDE01 !== \u{D83D}\u{DE01}. Inconsistency that's hard to explain to developers.

DC: This feature is more likely to be used by hackers than developers.

AWB: Two APIs

1
2
3
String.fromCodePoint (build string from integer values)
String.prototype.codePointAt

What's here, valid surrogate pair?

DH: Mixing the API levels is problematic, should it be scrapped?

...The problem in naming is the "At"

...If we're going to build code point abstractions, we really need a new data type.

NL: ICU has iterators for grapheme clusters, words, sentences, lines – all based on UTF-16 indices. Abstractions don't require different indices.

Need more here.

link 4.13 Destructuring Issues

A. Patterns discussion on es-discuss

Issue: ToObject() on the RHS? This is currenty specified and enables things like: let {concat, slice} = "";

This equivalence is desirable and maintain by the current spec:

1
2
3
4
5
let { foo } = { bar: 42 }
===
let foo = { bar: 42 }.foo;

A syntax for pattern matching against objects

1
2
3
4
match({ bar: 42 }) {
case { foo } { console.log("foo") }
default { console.log("no foo") }
}

1
2
let { ?foo } = {}
let ?foo = {}.foo // _wtf_

DH: Pure WAT. Let's pick the most common case and address that. You cannot presume to cover everyone's pet case

What is the right thing to do.

DH: Future pattern matching

LH: Reiteration of correct matching vs intention

More discussion, defer until AR is present

1
2
3
let { toString: num2str } = 42;
===
let num2str = (42).toString;

Consensus without AR is to impute undefined for missing property when destructuring, and if we add pattern matching, use different rules for patterns compared to their destructuring meaning.

BE talked to AR at dinner on day 2, thinks he heard this and may have agreed (to avoid breaking consensus). Need to confirm.

B. Defaults

Explicit undefined value triggerw use of default value initializer.

1
2
3
4
let foo = (x = 5) => x;
foo(undefined) // returns undefined by current draft
foo() // returns 5 by current draft

Issue: is this desirable? dherman and others think an explicit undefined should trigger use of default value. use case in support

1
2
3
4
5
6
7
8
9
function setLevel(newLevel=0) {light.intensity = newLevel}
function setOptions(options) {
setLevel(options.dimmerLevel); //missing prop returns undefined,
should use default
setMotorSpeed(options.speed);
...
}
setOptions({speed:5});

Note same rules are used for both formal parameter default values and destructuring default values.

1
2
3
4
let foo = (...x) => x.length;
foo(undefined) // 1
foo() // 0

Need summary. decision: change spec. to make undefine trigger use of default value.*

C. Unresolved issues related to iterator naming/access

  1. Be able to destructure things that did not opt-in
  2. No implicit coercion
  3. Array.from

spread works on array-like destructuring has rest pattern

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import iterator from "@iter"
function list(x) {
return iterator in x ?
[ y for y of x ] :
x;
}
[a, ...] = list(jQuery(selector));
[a, ...] = list([...]);
[a, ...] = list(function *() { ... });
f.call(f, ...args)
same as
f.apply(f, args);

link Consensus/Resolution

  • change spec. to make undefine trigger use of default value.

(DH) iterator is a unique name -- can't be public because iterable test not confined to for-of RHS

Destructing and spread - no iterator protocol. (return to existing draft semantics of arraylike — [Cannot be both iterable and array-like])

Array.from should... (this is a change to current specification)

  1. Attempt to use the iterable protocol, if cannot...
  2. Fall back to using Array-like protocol
  3. Always return a copy

(Filed: https://bugs.ecmascript.org/show_bug.cgi?id=588)