April 10 2014 Meeting Notes

Rick Waldron waldron.rick at gmail.com
Tue Apr 15 07:26:56 PDT 2014

# April 10 2014 Meeting Notes

Doug Crockford (DC), Brian Terleson (BT), Luke Hoban (LH), Dmitry Lomov
(DL), Waldemar Horwat (WH), Allen Wirfs-Brock (AWB), John Neumann (JN),
Rick Hudson (RH), Rick Waldron (RW), Eric Ferraiuolo (EF), Jafar Husain
(JH), Jeff Morrison (JM), Seo-Young Hwang (SYH), Mark Honenberg (MH),
Caridy Patino (CP), Yehuda Katz (YK), Niko Matsakis (NM), Ben Newman (BN),
Sebastian Markbage (SM), Mathias Bynens (MB), Rafael Weinstein (RWS), Mark
Miller (MM),

YK: Revisit new TC39 process. Phase 2?

LH: Phase 2 is experimental

YK: Yesterday, was told Phase 2 is too late for feedback

LH: My sense was that the issue is communication

## 4.10 Modules Feedback
(Brian Terlson)


(need slides)

BT: This is feedback, not necessarily requests for change.

**Key Points**

- Module + Import Syntax
- Hard to remember which does what?
- Having two import syntax forms seems undesirable

- Conceptual model is a departure from what folks are used to
- Reason for departure is not immediately clear (cycles?)

YK: When I teach modules, I don't teach the `module ...` form at all

BT: The only way to get a binding to the module itself

LH: Can be used almost as a first-class object reference

YK: Cutting at this stage is not bad, I can champion researching the

CP: This may break the ability to statically verify the module?

LH: If you did:

module foo from "bar";


If `foo.whatever` didn't exist, would be an error

Question about this being in the spec?

YK: The solution is to go back and determine whether or not `module foo
from "..."` is necessary or can be cut.

(This does not affect default imports)

AWB/LH: "module" was for the `Math` case?

JM/RW: `Math` case could very well be defined as a default export.

YK: Can use the following to bring in a module solely for side effects:

import "foo";

WH: How is work divided between the import and the System.get?

YK: `import "foo"` is just the mechanism to ensure the import of a module
without specific bindings. For side-effecting modules.

WH: So the System.get is not neeed to bring in a module solely for side

YK: It's there if you want to get a handle to the module.

LH: This is very close to the semantics of the `module` keyword, unless
missing something

Discussion re: is the issue superficial syntax?

LH: Maybe (recommended by AWB) `import module Foo from "..."` to replace
`module Foo from "..."`?

YK: May not be trivial
... The feedback is that the default export being the main module _and_ a
property is confusing.

LH: (confirm)

YK: (walks through explanation)

BT: (continuing)

- Lots of ways to import and export
- As many as 3 different ways you would consume jQuery depending on what
jQuery exports
- See:

import $ from "jQuery";
var get = $.get;

// vs.

import { get } from "jQuery";

RW: The first two serve different purposes

var Foo = require("foo");

// and

var Foo = require("foo").Foo;

// The latter is the same as:
var f = require("foo);
var Foo = f.Foo;

Discussion about general understanding of node module design

YK: The important point is that if the first is used where the second is
needed, user will get an error immediately and will change to the correct

LH: As much as I think this may be confusing, I don't want to change it
because it I don't want to risk breaking cycle support.

YK: Cycles are not and should not be a thing that the user has to think

RW: (prompting to move on)

BT: (continuing)

- Lack of support for dynamic scenarios

BT: want write a function that took a module name as a param, import that
module , mutate it and re-export. it would look like importing the original
module, but actually getting the modified.

AWB: Can do this at the Loader level

BT: Confirms.

CP: We've been able to prove that this works quite well.

#### Conclusion/Resolution
- Revisit `module foo from "..."` (YK)

## Reviewer sign up

## Revisiting: Initializer in for-in

AWB: New information:

OH: To clarify JSC encountered breakage in the syntax. Only case we’ve seen
is (presumably) author changing their mind about type of loop, so we
_no-op_ the expression.  No execution at all.
...Unclear about what we’re saying about the let case. I would be opposed
to leaking the redundant initialiser into for (let blah of/in …)
... Would be great to eventually nuke it.

AWB: Likely won't have any new information in May?

OH: All internal builds have this change, so we'll have users reporting.

AWB: Do we move forward nuking it, or as a syntax with no semantics? In
main body or an annex?

WH: If we retain the syntax, it should do what it has always done. Why
should we have it do something different?

MM: If we leave it in, we have to accept the side effects it causes.

YK: Why does JSC want to ignore evaluation?

OH: To discourage its use.

WH: If we wish to discourage its use, we should move the initializer syntax
to Annex B (and have the Annex B semantics reflect its historical behavior,
not new behavior).

RW: Any code that has been run through JSLint/JShint will not have this
syntax, rejected outright.

AWB: Continue to have it removed, allow the syntactic form in Annex B

MM: Another observable thing... no properties, the var decl is visible
after the loop
... The only reason to leave it is concern about breaking something bizarre?

WH: Isn't the var always visible? It's hoisted

MM: Yes, but the initialization value being assigned is only visible if
there are no properties

WH: What's the impetus to keep the initializer syntax but change the
semantics of the syntax to something different in Annex B?

AWB: Easier to put in the syntax with no semantics

MM: Either flush it, or put it in with the old semantics

AWB: Flush it and let implementations do what they do

BT: If implementors aren't getting rid of this, new runtimes will implement
to match the web

MM: If we expect all browsers to implement, we should codify. If we expect
not to implement, then don't codify. Cross browser content

Discussion, re: comparison to `__proto__`

MM: Other than JSC, any other impl?

BT: If JSC doesn't feel comfortable, unlikely that IE will

AWB: There has only been discussion at Mozilla

OH: We have evangelized, no one heeds

MM: Mozilla evangelized successfully

OH: Performance punishment (log messages for features that need to be

BT: Willing to wait for Mozilla to guide

WH: Does test262 cover this?

BT: Probably, the test will have to be removed.
...Spec should reflect reality.

WH: In favor of taking it out and seeing if we can get away with it. We can
put it back in Annex B. The work to take it out is not wasted.

BT: If all three browsers continue supporting, we agree to put it in the
spec, at least in Annex B

#### Conclusion/Resolution
- Mozilla willing to ship a patch in nightly for experimentation

## Revisiting: Generator Issues
(Jafar Husain)

Slides: [Allowing-Generators-to-Compose-over-IO.pdf](

JH: Generators can't abstract over sync or async IO.

**Two Ways to Iterate**

var nums = function*() {
  yield 1;
  yield 2;


function Iterable(generatorFunction) {
  this[@@iterator] = generatorFunction;

**Creating Iterables**

let nums = new Iterable(function*() {
  yield 1;
  yield 2;
  yield 3;

**Iterating Iterables**

for(let x of nums()) {


let iterator = nums()[@@iterator],

while(!(pair = iterator.next()).done) {

**IO Streams as Iterables**

function getLines(fileName) {
  return new Iterable(function*() {
    let reader = new SyncReader(fileName);
    try {
      while(!reader.eof) {
        yield reader.readLine();
    finally {

**Iterable Composition**

Iterable.prototype.map = function(projection) {
   let self = this;
  return new Iterable(function*() {
    for(let x of self) {
      yield projection(x);

Iterable.prototype.takeWhile = function(predicate) {
  let self = this;
  return new Iterable(function*() {
    for(let x of self) {
      if (!predicate(x)) {
      yield x;

YK: Need to address Brendan's objections from yesterday

JH: The crucial problem: the iterator claims to be an iterable and it's not.
...If async generators return Iterables, not Iterators.

WH: How

JH: If I accept an iterable and invoke `@@iterator`, I would expect to get
a fresh iterator from each call

MM: everythime you for-of you expect to see "the stuff"

JH: Iterators are claiming to Iterables, which is a lie.

NM: An Iterable creates Iterators, Ite

AWB: An iterator that itself has an @@iterator is an iterable

WH: The distinciton is similar to C++'s distinction between input iterators
and forward iterators. Input iterators are not replayable.

JH: This is a leaky abstraction. Two calls to @@iterator on the same
iterator type will cause the same iterator to be shared unexpectedly in two
different code paths.

Discussion re: the process for handling this.

YK: This should've been presented to the feature champions first.

MM: If these are issues that we're going to address, they need to be
addressed in ES6

AWB: If we address it in ES6, the only way is to drop Generators from ES6

YK: The best approach is to first discuss with champions of feature

MM: Let's first hear the issues

YK: Disagree with first hearing of the issue in this forum. Jafar could've
been more effective by bringing this to Dave and Brendan first.

WH: I want to understand the issues. This is the best forum we have at this

AWB: This is a long resolved and accepted feature, may have non-optimal
characteristics, but agreed on. We're long past changes like this.

LH: Let's focus on the problem, not the solution

(New example. copy from slide when available)

OH: you need `self` to finish somehow after the `break`

JH: you need the `return` semantic
...not a problem in Python, because they have StopIteration. This impl had
StopIteration and close and both removed.

LH: (Luke please fill in the comments made re: StopIteration and finally

WH: Please explain what you're arguing for:

JH: Add a `return()` to generators

LH: return would trigger the `finally` clauses

WH: why in addtion to `throw`?

LH: throw hits `catch` blocks

WH: for-of would call that if you break?

LH: Yes, but that's a separate level of the proposal

AWB: No way to run only the `finally` blocks and not the `catch` blocks

WH: Is there some other aspect?
...Iterator is a once through, cannot go back

JH: Make function * to return Iterable

YK: The most salient use case: break but want to continue to use the

AWB: Let's just talk about return, no way to force the finally to run
...Specific issues that Andy brought up need to be addressed. Additionally
need to convince why the agreement to those issues was incorrect.

YK: The break is ambiguous

JH: As long as you never use the for-of syntax, you're fine


    - for...of always assume generator creation
    - for...of alwayss terminates generator function

Lost in cross talk...

NM: If you know that iterable creates a fresh iterator, it's very
reasonable to close it every time. If you don't know that, then Andy's
argument holds.

JH: The value proposition of for-of is that you don't need to work with

AWB: We _could_ add a `return()` method.
... It's a bigger change, but we could make for-of invoke `return()` on
exit or completion

YK: doubt we can come to a conclusion on this

AWB: We _must_ come to a tentative conclusion

JH: Confirm, let's try.

MM: Agree with Allen

#### Plausible Solution:

- continue to have iterators have an @@iterator, classified as iterables
- continue to have generators return an  iterator+
- continue to for-of on an iterator
- we change:
- generator instances have a `return` that when invoked, caused the yield
point to take the return path, returning the argument that was provided to
the return method. [AWB: actually, needs to return a IteratorResult object:
  {done: true, value: returnMethodArgument} ]
- the for-of behaviour is extended with an equivalent of a finally cause
that feature tests for presence of return, if present, call it on any
abnormal exit from the loop, normal or abnormal. [AWB:no change is
necessary for normal loop complextion because the return from the generator
body that sets the completion object to {done: true} will run any finally
code in the generator body]
- AWB: a 'return' call that  interrupts a yield* needs to be propagate to
the inner iterator, just like a 'throw' call.

YK: Recalling Brendan's opposition

MM: The new information: if you want to partially consume an iterator,
don't use for-of.

Discussion about process.

RW: (interupt) We can't have a discussion with the champions without
considering the issue an dhaving a meaningful record of the discussion.
(consider a process note)

LH: Notable, C# does what we're proposing. C# also doesn't allow `yield` in
`finally`. No guarantee that we'll run to resource completion.

AWB: No guarantee

MM: No asking for consensus?

AWB: I am. This room needs consensus before we bother including champions

MM: Not a TC39 consensus, a provisional consensus until the champions have
been involved.

Discussion about process.

AWB: If we dont decide something, this will float to next meeting.

YK: Proposal: Jafar, Allen, Ben, Dave and Brendan need to work this out

MM: Any dissent from the proposal stated being presented to the champions
and allow a decision to be made without further discussion.

WH: Objects to this problem *not* being solved. Object to the status quo of
doing nothing. Some solution (such as MM's above) must be found.

#### Conclusion/Resolution
- Unanimous agreement to allow the champions, Allen Wirfs-Brock, Brendan
Eich, Dave Herman, Andy Wingo, Jafar Husain, Ben Newman to solve this
- Allen Wirfs-Brock to originate the email for discussion.
- Reference material:

## Decorators for ES7
(Yehuda Katz)

Slides: (need slides)

YK: Presenting aspects of common use cases not yet covered by ES6 `class`.

Knockout.js example (compute the value of a property)

WH: Do you want to use functors to produce functions that are per-class
(i.e. on the prototype) or per-instance?

AWB: Per instance wants to be handled in the constructor

YUI example (a readonly property)

LH/YK: Sometimes you want to say a method is readOnly

AWB: No declarative way to describe the per instance state

Angular example

LH: (explanation) when I declare a class, I also want to register it with
some other system

ES6 Experiments: Angular

class NgBind {
  constructor(element) {
    this.element = element;

AWB: The "@" used to define an annotation

JH: Point out that this is inert meta data

Userland Classes: Ember

App.Pserson = Ember.Object.create({
firstName: null,
lastName: null,
fullName: Em.computed(function() {
return this.get('firstName') + ' ' + this.get('lastName');
}, 'firstName', 'lastName')

ES6 Experiments: Ember

class Person extends Ember.Object {
  - dependsOn('firstName', 'lastName')
  get fullName() {
    return this.get('firstName') + ' ' + this.get('lastName');

  - on('init')
  - obeserves('fullName)
  fullNameChanged() {
    // ...deal with the change

YK: Goals:

- Decoration of methods and accessors
- Decoration of future declarattive property syntax
- modifcation of the property descriptor in addition to its value
- can wr
...need slide.

Property Decorators

function readonly(prototype, name, descriptor) {
  descriptor.writable = false;
  return descriptor;

class PostComment extends HTMLElement {
  - readonly
  - on('click')
  clicked() {


  - observes('value')
  valueChanged() {


Close desugaring...

// after PostComment declared

Object.defineProperty(PostComment.prototype, {
  clicked: {
    value: function() { ... },
    writable: false


MM: What order?

YK: Bottom up


function memoize(...dependencies) {
  return function(prototype, name, descriptor) {
 // ... see slide for specifics

class {
  - memoize('firstName', 'lastName')
  get fullName() {
    return `${this.firstName} ${this.lastName}`;

NM: This is very similar to Python and there is a large history of people
doing amazing and terrifying things

MM: The descriptor provided is the descriptor that, in the absense of the
annotation, would've been installed on the property?

YK: Yes, only providing the descriptor

MM: Only the descriptor returned by the final annotation is used to install
on the property.

AWB: Example:

class {
  - dynamic(function() { ... })
  boringMethod() {}

YK: Yes, but there is another class annotation proposal better suited


(extensive slides)

MM: Order of accessor case?

YK: Statically

Static Semantics
- `MathodDefinition` and `static MethodDefinition` have a list of
`DecoratorExpressions` (AssignmentExpression)

WH: How does the decorator know whether you're decorating a getter or a
setter from a get/set pair? It's reasonable to request different
decorations for the two — decorate the getter as public and setter as

YK: It can't. Right now the proposal merges the get/set descriptors into an
aggregated descriptors.

AWB: This assumes that the property is created with an aggregated
descriptor, but DefineOwnProperty knows to only set the properties provided
and doesn't set the other properties to undefined if they're not present.

MM: If you want the accessor to be non-configurable, you have to set them
at once.

YK: If you don't aggregate, using a single decorator for a get/set pair is

WH: If you do aggregate, using a decorator for just a get or a set is
impossible. That's a necessary thing to do and more closely matches the

MM: The getter for "foo" is non-configurable non-enumerable, and the setter
for "foo" is non-configurable enumerable, it's impossible

YK: Need to find a solution to disallow creating contradictory descriptors

AWB: Overriding ClassMethodDefinition?
MM: Overriding MemberOfLiteral definition?

(Note: ClassMethodDefinition and MemberOfLiteral don't exist)

More Custom Syntax

class Article {
  + hasMany('comment')
  + belongsTo('user')
  + attr('title')
  + attr('author')
  + attr('body')

  constructor() {


  - dependsOn('title', 'author)
  get byline() {
    return `${this.title} by ${this.author}`;

MM: The reason not using "@" was for two mechanisms?

YK: Yes

LH: Don't want to put a method decorator on a class level annotation.
... May not be the best solution to this problem. What you want is
something declarative.

WH: How do you create prototype properties out of thin air?

YK: Use the + form.

WH: Then you could do this, right?

class Article {
  + hasMany('comment')
  + belongsTo('user')
  + attr('title')
  + attr('author')
  + attr('body')

  - dependsOn('title', 'author)
  + generateMeAMethod

  - dependsOn('title', 'author)
  get byline() {
    return `${this.title} by ${this.author}`;

YK: No, it's passed the class

AWB: The + form, does it involve the descriptor?

YK: No. The + form takes a class object, not a property descriptor.

WH: The cool thing is that - is composable. It would be weird to not be
able to apply it to prototype properties that happen to be created out of
thin air

Discussion about the problem faced across instance and prototype properties.

WH: Want declarative properties too.

MM: Use method decorators on computed declarative properties.

YK: Yes

WH: Concerned about syntax ambiguities

WH, AWB: Need to coordinate this with declarative properties proposals

AWB: Careful abt not using this to do things that we may do in language.
This is targetted at library designers

MM: Creating this whole "module" thing, but pre-populating it with system
modules. Could pre-populate with system decorators.

RW: There is long precedent, appropriate, etc.

RW/NM: Decorators made available in a decorators modules, avoids
restricting user code

AWB: We should try to follow the same guidelines that we define with regard
to defining library code in the language vs. library code in user space.

MM: All basic descriptor manipulation could easily be pre-populated.

YK/RW: configurable (sets configurable: true), nonconfigurable (sets
configurable: false)

LH: Encourage the Angular designers to bring forward their proposal as well.

#### Conclusion/Resolution
- Start a strawman
- work together with others that have class syntax extension proposals
- consider other proposals

## Ecma 402 Updates

AWB: updates need to be made to Ecma 402, but I dont have the time/bandwidth

#### Conclusion/Resolution
- RW volunteers to attempt
- AWB will provide basic summary information

## Preview of asnyc/await
(Luke Hoban)


A few updates since last time:

1. Ben Newman has implemented async/await in regenerator
2. Async arrows feedback
3. await at top level
4. Is await* needed?
5. Ordering of static + async: static async foo() { }

Discussion of async arrows from

LH: If we cared about being forward compatible with eliding () in arrows,
we could be conservative with [no line terminator] :

Several: async(foo, bar) => ... looks too much like a function call.

LH:  If 'async' were 'function', you likely wouldn't say that.  Once
editors colorize, this will be less of a concern.

WH: you're not proposing to make "async" a keyword?

LH: Contextual keyword

[Discussion of syntax and no-line-terminator-here]

LH: Questions about whether 'await' should be allowed at top level.  We
could add to the module top level grammar, not the script grammar

WH: If it's usable in modules outside async functions, would await be a
contextual keyword inside modules? It isn't right now.

MM: That would be a breaking change from ES6.

?: We could disambiguate in grammar.

WH: No. Is x = await(foo) a legacy ES6 function call or an await call?

LH: Good point, we'd need to reserve "await" in modules in ES6.

LH: Original proposal included an optional "await*" syntax that was sugar
over "await Promise.all(...)".  It was unrelated to "yield*" which has no
meaning in async context.

MM: Using await * that is not analogous to yield * is bad, let's take it
off the table.

LH: Agreed - we'll remove that from the proposal.

LH: Current proposal requires "static async" to be ordered that way for
async methods.

Several:  Sounds okay.

#### Conclusion/Resolution
- "await" needs to be reserved in module context
- Keep async arrows, and keep the conservative grammar with [no line
terminator] annotations
- Tentatively believe await at top level in modules should be okay.

## Closing

JN: Want to thank Mozilla for hosting us and appreciation to Ecma for
dinner last night.

#### Conclusion/Resolution
- Unanimous agreement :)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140415/3c634988/attachment-0001.html>

More information about the es-discuss mailing list