July 28 2015 Meeting Notes

# Rick Waldron (9 years ago)

(Slides are at tc39/tc39-notes/tree/master/es7/2015-07 )

July 28 2015 Meeting Notes

Allen Wirfs-Brock (AWB), Sebastian Markbage (SM), Jafar Husain (JH), Eric Farriauolo (EF), Caridy Patino (CP), Waldemar Horwat (WH), István Sebestyén (IS), Mark Miller (MM), Adam Klein (AK), Michael Ficarra (MF), Peter Jensen (PJ), Domenic Denicola (DD), Jordan Harband (JHD), Jonathan Turner (JT), Paul Leathers (PL), Chip Morningstar (CM), Vladimir Matveev (VM), Ron Buckton (MS), Brian Terlson (BT), Alan Schmitt (AS), Ben Newman (BN), Mohamed Hegazy (MH), Abhijith Chatra (AC), Tom Care (TC), John Neumann (JN), Dave Herman (DH), Brendan Eich (BE), Rick Waldron (RW), Mike Pennisi (MP)

Introduction

BT: (logistics)

AWB: I will chair until John N. arrives.

Adoption of Agenda

AWB: tc39/agendas/blob/master/2015/07.md

YK: Propose that future agendas be organized by stage advancement

(Agreement)

IS: Need to add Ecma Secretariat items (Allen adds) like report from the GA.

Conclusion/Resolution

  • Approved

Approval of Minutes from May 2015

AWB: Posted on Github and es-discuss

IS: Ecma is archiving (mirroring) the most significant documents from GitHub, like technical notes as well as summaries associated with the agendas. This practice should satisfy both the requirements of Ecma as an SDO as well as of Tc39.

Report from Ecma Secretariat

4.i Status of ISO/IEC Fast Track of ECMA-262 Ed.6, ECMA-402 Ed.2 and

ECMA-404

IS: Need an Ecma-262, Ecma-402 and Ecma-404 package "Explanatory Report"

  • Next project is "linking" the three explanatory reports in one
  • Then discussion on the fast track started

AWB: Can we push through our current documents, as-is? Without changes?

IS: Similar to 5.0 -> 5.1, editorial changes allowed. Any technical

changes, no. Concerns about stability.

AWB: Concerns about an ISO document that says one thing, vs. the Ecma document that says another.

IS: Can disallow discrepancies, therefore it is always the policy to synchronize the standard on both sides

WH: What happens if the ISO reviewers discover technical issues?

IS: The problem is that the yearly update for JTC1 might to be too fast. We are elaborating on them. Theoretically worst case, we withdraw the "fast track"

WH: [incredulous] Withdraw instead of fixing bugs? That wouldn't be nice.

IS: (explains why fast track). We have started this about 17 years ago, as long TC39 came out with big time gaps between Edition, no problem, but the current "turbo speed" like standardization (update) may create problems in synchronization. we are discussing this new thing with ISO.

AWB: Good to communicate to ISO

  • We appreciate technical feedback
  • Feedback will be put into the next edition as part of the on going process

IS: Explained to Rex Jaeschke (JTC1 SC22 Chair) the new schedule. Normally ISO likes to update standards every three years, have expressed our one year schedule plans.

WH: Afraid ISO might not like "take it or leave it". In the past, we got excellent technical reviews from them and have integrated the changes into the ISO standard and to the Ecma standard.

AWB: But that would be next June

WH: That's how we've always done it. The ISO version was a year behind the ECMA version. If we don't integrate the known defect fixes, the ISO version would be multiple years behind ECMA.

AWB: Ignoring unknown issues, we have 5 or 6 technical issues that could comprise a 6.1

RW: If we have a yearly release for full edition points, perhaps we can also include a 6 month "sub release" to address minor changes to current

YK: Not unreasonable when the work is done by a group using shared tools

IS: Theoretically in Ecma we could have a 6 month correction cycle (TC52 Dart uses that). Depends on TC39 what they want.

AWB: What does the GA think about doing this process every six month?

IS: no problem there, this could be reasonable solution, for Dart it has been accepted. Of course Impose a deadline of 2 months before December GA meeting for the version to be voted upon and published.

RW: Can correspond with our September meeting.

IS: (agreed)

AWB: Trivial to make minor changes, willing to work through the first round as we transition editorship.

  • Need to decide this meeting and produce a draft for approval at next meeting.

bugs.ecmascript.org/describecomponents.cgi?product=ECMA-262 Edition 6

RW: Does this need to include the ISO review comments (Waldemar's concern)

YK: Would like to come back to this after we have a more in depth discussion about the future of our tooling.

Discussion about what we produce.

AWB: We can produce errata any time, but it's not the standard

DD: If we have the base covered, avoiding shipping bugs, do we publish errata every year or every six month?

WH: It's not ok to ship a standard with known defects. We can publish standards on whatever schedule we want, but anything we publish should have all known defects fixed.

YK: Think "annual" is enough time to fix bugs

AWB: The issue is ISO. There is concern about divergence between those two documents (ISO document with changes made by their reviewers, Ecma version)

BT/IS clarifying why we need ISO version?

BT: Why?

WH: There are benefits to ISO publication

AWB: There are organizations that may require

IS: Public procurement, if it's an Ecma standard, maybe problematic. ISO is in the "highest level" of international standard category.

BT: Are there concrete examples of using ISO specification over Ecma?

(Spending too much time on something we don't know the value of)

DD: Propose that we don't do this process unless an external request for it is made.

IS: We are already for 17 years in this process, and it is expected that we continue for future editions as well. So this is automatic and not exteranl request is needed. How to explain why ES 1, 2, 3, 5 & 5.1 are ISO standards, but 6 and 7 etc. not and what if Ecma is already e.g. at 7 and ISO still on 5.1?.

Can we be forced to do this?

IS: Yes, the current rule for synchronization "forces" it.

YK: (clarify) Once we issue any ISO spec, we're required to maintain?

Several "yes"

WH: We don't want to destroy the relationship between Ecma and ISO

STH: How does is hurt to not create ES 6.1?

YK: ISO was ok with a two year wait for 5 to 5.1, should be ok with a year between 6 and 7

WH: But much longer since 5.1

AWB:

  • Errata?

Discusson re: schedule, responsibilities, etc.

AWB: We will submit to ISO, with exact same text (subject to ISO naming, etc). But the text will include any known errors.

WH: No, they have to be fixed. I'm not ok with shipping standard with defects known to us.

DD: We agreed to fast track at the last meeting and Waldemar is now disagreeing?

WH: Incorrect

DD: You said you won't allow us to fast track with defects

WH: No, we must fix defects

STH: Why does fast track require fixing errata?

WH: Not a lot of work

DD: You're saying that you no longer agree to fast track

WH: We will get ocmments from ISO reviewers, these will identify defects, these need to be fixed. It is our job to fix

CM: Exactly the proposal: take the existing text and put it in the pipeline and publish the errata later.

YK: Treat ISO as an LTS?

WH: That's what it is

DD: Can we have members of the committee that are responsible for incorporating the errata, as a separate task.

AWB: That's the editor's job. Incorporating errata is not a lot of work.

RW: This is exactly my suggestion, but with a schedule requirement.

Discussion about who and how.

AK/JT: What is the cut off for known defects?

DD: Suggest that we let whoever volunteers be responsible for making those decisions

YK: With better tooling, we could really just do this as branches in a repository where all work is tracked.

AWB: Don't think that any editorial difficulty. Bigger isssue: what are we going to do with ISO on a regular basis? Yearly ISO and it's the same document?

BT: Agreed.

AWB: Ideally we'd have "fast track authority", submit the Ecma document and they either take it or leave it.

YK: Can we revisit this after we've read the agenda items? (Specifically item 5)

AWB: That item is Editorship?

YK: That seems to determine tooling.

JN: Assignment of Editorship role.

BT/AWB: Yearly release, give them to ISO without change, accept them as is. Take their changes and roll them into next year's edition.

WH: This is agreed to an incorrect assumption. All ISO comments must be addressed.

IS: That's correct. That's required by the ISO process.

BT: If Istvan can convince ISO to accept yearly releases "as-is", are you ok with this?

WH: If ISO can accept as-is, then let's discuss this again, but I don't think they can

IS: I told ISO at the last meeting that we are moving much faster and that we need to create a new way to submit. This is a way to handle that and I can present it to them as a solution. Normally, they don't update until every 3 years. I pointed out the issue with their timeline and they agreed. This is a possible solution and I will work with them to sort out this problem.

WH: Are they ok with not making comments?

IS: From some members, but not all, awaiting final word.

WH: Not ok with making decision until we know where they stand.

Conclusion/Resolution

  • Yearly release, given to ISO without change, to accept as is.
  • No sub releases
  • Publish errata as follow up
  • Take their reivew comments/changes and integrate them into next year's edition.
  • Istvan will present this to ISO as a solution

Propose Life Membership for Allen Wirfs-Brock

(Rick Waldron)

RW: As we have for Brendan, I'd like to propose inviting Allen Wirfs-Brock as a lifetime member of TC39

IS: Such a category does not exists officially at Ecma, only some freedom for the Secretary General to allow partication as invited expert. He will bring this to Ecma Management for seeking agreement. This is a special case, and I am confident.

Conclusion/Resolution

  • Istvan to get approval

5 ECMA-262, Editorship

JN: Need to appoint a new editor, only one volunteer has come forward and that's Brian Terlson.

  • Motion to appoint Brian

YK/RW: Seconded

JN: Discussion?

WH: Do you see your approach as different from Allen?

BT: Only in that I'm a different person, but generally the same. I'm not Allen, but I will do my best.

AWB: Appropriate to also appoint a manager for the content that we're producing.

Conclusion/Resolution

  • Brian Terlson is new editor of Ecma-262
  • Unanimous consent

Discussion of the Manager Role

AWB: Useful to have some web content which will need a manager

Discussion, re: content manager

"web master"

IS: Need procedures to archive the github material

AWB: Unless someone wants to volunteer now, then let's resolve to appoint someone by the next meeting.

JN: Allen please generate a "job description"

Conclusion/Resolution

  • Allen will produce a "job description"
    • Coordinate with Brian
  • Submit to member companies for review
  • Member appointed to the position at next meeting

Exponentiation Operator

(The room is very excited about technical discussion finally starting.)

RW: SpiderMonkey is ready; V8 is ready; spec material is ready rwaldron.github.io/exponentiation-operator/; it meets the requirements for stage 3

WH: This is incomplete; it is missing details on the lexical grammar.

RW: Agreed; I can address that issue before the end of this session. Perhaps we can revisit in the coming days.

DH: Let's avoid a precedent that if anyone finds any minor hole, they can stop advancement.

WH: This is an issue of completeness

DH/BT: The resolution of this problem is obvious and trivial to implementors

AWB: We need to improve the process document to include expectations for reviewership

DD: The process document is now published as an HTML document in an public repository on GitHub.com. I have migrated it from Google Docs with no changes to content. I have opened two issues to discuss details that have historically vexed this committee.

WH: I have no doubt that you can address this by the end of this meeting.

RW: I am literally done.

BT: We have agreed that technical issues should not block advancement to Stage 3. Does anyone object to advancement?

AWB/DH: We have technical questions, but they have no bearing on advancement to Stage 3.

(break for lunch)

Conclusion/Resolution

  • Approved for stage 3

6.2 RegExp.escape

(Domenic Denicola)

benjamingr/RegExp.escape

Slides

DD: (presents slides)

YK: Don't make user think about escaping.

AWB: Generate a complete regexp from string. Append cases

WH: What does it mean to create a regexp from a string? (w/r to Proposal Ruled Out)

AWB: Regexp construction that will exactly match

YK: A simple example: a lexer, the lexemes provided as a string

DD:

SyntaxCharacter Proposal

  • Escapes string just enough to be used as a RegExp

AWB: Used as argument to the RegExp constructor

DD: yes

Safe Wth Extra Escape Set

  • Escapes everything the SyntaxCharacter proposal does
  • Escapes - addl. for the context sentive inside-character-class matching
  • Escapes hex numeric literals (0-9a-f) at the start of the string in order to
  • Less readable output but safer

WH: Escaping d by replacing it with \d completely changes its meaning. The latter matches any digit but not the letter 'd'.

YK: Issue is RegExp.escape(...) what?

WH: Second use case ( benjamingr/RegExp.escape/blob/master/EscapedChars.md, 0-9a-fA-F) is not useful. There is no good reason for someone to concatenate the erroneously short (three digits instead of four) \u004 to user-defined input. The first use case there is also not common.

MF: Should be a RegExp.compose, not use + to concatenate strings for RegExp()

new RegExp("\\u004")

AWB: illegal in the grammar, but allowed in the annex extentions (annex b grammar allows < 4 characters following the \\u)

WH: Why would you do this on purpose?

WH: How do you escape these things? \d, or \0 which does not mean 0

MM: Issue about fragment hazards, not using + for composition. I actually think that a template string tag is the solution

DD: Extended "Safe" Proposal, Allen had concerns?

AWB: ES5 takes efforts to roundtrip the string returned for a regex has forward slashes

WH: RegExp's toSource creates a string that, when eval'ed, produces a valid RegExp

DD: No change to output of RegExp.prototype.toString

DD: benjamingr/RegExp.escape#4 explains why not a template string tag, but reviewing now, the arguments are not strong

MM: You get the escape functionality in terms of the template string tag.

MF: Concerns about unnecessary escaping

DD:

WH: Readability costs. Don't want RegExp.escape to turn '7' into '\u0037'.

MM: template string doesn't have those costs

DD: cannot compose a variable number of strings together with template string tag

YK: Assumes certain amount of "static-ness".

... Would like to see an injection scenario that seems realistic.

DD: it's possible, it can happen. Reasonable for a TC created solution to address all the cases. All we need to do is address all of the cases presented, at the beginning of the string

AWB: Why do we thing there is one escape function that covers all cases?

WH: Whoever is writing the things that are not escapes, limits themselves to a subset of "well behaved regexp". In a well-behaved regexp:

  • don't end it with a single \
  • don't end it with \u002
  • don't end it with \1
  • don't end it with (?
  • etc.

DD: What if you want to match backreference \1

WH: If you want to do it just before a concatenation point, write it as (?:\1). A trailing backreference is such a rare case, this is a reasonable constraint to do to simplify readability of all escaped strings that start with digits.

MM: Object to template string solution?

WH: No. My argument is orthogonal to whether we use template strings or RegExp.escape. Object to escaping individual non-punctuation characters a, b, c, d, e, f, 0, 1, 2, 3, 7...

DD: Objection to any proposal but the SyntaxCharacter Proposal?

WH: No. Fine with other punctuation-escaping-only variants such as also escaping '/' if we choose to do so.

YK: Does SyntaxCharacter escape -?

DD: No

YK: That's a mistake

AWB: SyntaxCharacter has specific meaning

DD: Current thing on table: SyntaxCharacter and hyphen

  • Advocate for whitespace?

YK: Why?

DD: eval

Discussion re: template string availability

DD: Proposal coming from people that need to ship code to non-edge browsers

YK: Use today? Library code.

DD: Has been a request for a long time, give what's requested even if unsafe? Give them what they want plus things that make it safe? or make a new thing from template strings.

Discussion, re: issues with template strings in this use case

YK: Maybe template string API is flawed and needs work to be dynamic

MM: Agreed with need.

CM: this output from one piece of code to another

STH: The spec can say "the output looks like literally the input"

YK: People will then rely on it

STH: State the goal, then go back and specify to reach the goal.

DD: We've done this, and the constraints are illustrated benjamingr/RegExp.escape/blob/master/EscapedChars.md

MM: What is the motivation for readable output?

BE/YK: Debugging

MM: Ok, then issue is debugging vs creating less bugs?

DD: Then escape everything

YK/MM: Agreed

DD: Any objections to escape everything?

  • There's been a lot of work so far
  • Can we continue on this path?
  • Preference for template strings?

MM: I think the template string proposal is better in all dimensions

YK: Maybe do both?

  • Safe version of RegExp.escape
  • Template String solution

AWB: Stage 1? Will the champions know that this could change from RegExp.escape to template strings?

DD: Want to say that RegExp.escape can move forward for now

YK: ?

MM: template strings handle all of the malformed fragment cases

  • Small list completely safe?

AWB: and is 100% convinced is safe?

MM: eval thing is safer than

DD: "only beginning of string"

WH: What mark is suggesting conflicts with what I was saying

YK: What is the constraint?

WH: Readability

Ok to escape everything, but don't have to

MM: Rather not inro hazards, ok with either solution that doesn't

DD: Ok to advance is escape everuthing?

WH: if we don't, escape everything, unnecessary to escape "d" at the beginning of string

DD: This has been identified as a security issue

WH: it does't buy anything and there are others that aren't covered.

DD: Can you give example

WH:

new RegExp("\\" + RegExp.escape("x"))

MM: "\" is a regexp fragment.

WH: Yes (in this case), but in practice so what? There's nothing in the concatenation example that would ensure you only concatenate complete fragments.

MM: Right, this is still a security issue. Unresolvable by escaping due to the odd-even problem.

DD: Ok, the point was to handle all cases

YK: Non capturing parens solution

new RegExp("\\\\(?:x)")

WH: Stick to well-behaved

Each case fails where another does not. Template strings address all issues, but fails for not being dynamic

MM: Would Benjamin be interested in pursuing the template string solution.

DD: Will bring this to Benjamin

?: Need to work to resolve the caveats in RegExp.escape.

WH: The caveats of protecting against all possible prefixes are inherent and irremovable. I want RegExp.escape to move forward despite those. It's safe for concatenating arbitrary escaped user input with well-behaved regexp fragments.

MM: I'm not ok

Conclusion/Resolution

  • dynamic solution that has caveats
  • caveats cannot be eliminated
  • not confident that all issues can be addressed
  • want to see template string solution explored

6.i Advance Array.prototype.includes to stage 3

(Domenic Denicola)

tc39/Array.prototype.includes

DD: Walking through tc39/Array.prototype.includes#12

Conclusion/Resolution

  • Approved Stage 3

Introduce promise rejection tracking proposal

(Domenic Denicola)

domenic/unhandled-rejections-browser-spec#changes-to-ecmascript

DD: (introduction)

YK: (summarizing) Some want to be notified when a Promise is rejected without an error handler

  • Will be used as if any promse without an immediate handler to treat as a fatal error

MM: prefer this to solution had consider

YK: Easily be used incorrectly

BE: Regardless of our intentions, it will be misused

  • What do you do with the promise?

DD: Use to correlate

  • dedupe on client

Discussion, re: potential hazards

YK: People often try to deal with promise debugging incorrectly

MM: This provides diagnotistic tools that allow for better debugging

YK:

MM: Instead of using the turn boundary, await gc, but gc may never happen

  • Intead of calling something to notify, a query API: did a promise get rejected? provide reason

DD: (refocusing) All I'm hoping for is the addition of these non-observable steps to the specification (showing domenic/unhandled-rejections-browser-spec#promise--executor- )

AWB: Nothing there that an implemenation couldn't do in terms of the current spec, it's totally allowed.

DD: You'd have to say "insert steps here"

AWB: When putting in the hooks, we more than say "this is allowed", we're saying "this is supported"

BE: This is more like a debugger API

Agree

YK/MM: An innocent refactoring to register a rejection handler

MM: The utility of having a diagnostic outweighs the noise of introducing

DD: There is no delay, occurs immediately, at the earliest step possible

MM: If I call Promise.reject?

DD: Will trigger the HostPromiseRejectionTracker

YK: Persuaded by Mark's argument

Discussion, re: .done

AWB: Different promise's can have different handlers? No

AWB: no reason an implementation needs to define HostPromiseRejectionTracker, so a default handler should be specified.

DD: Didn't see something like that

YK: Move to stage 2, because already implemented.

Discussion, re: stage process? Yes.

Conclusion/Resolution

9 Tooling Updates

(Brian Terlson)

Slides

BT:

Grammarkdown (Grmd)

  • rbuckton/grammarkdown
  • Plain text syntax for specifying ECMAScript grammar
  • Support for multiple emitters—MD, HTML, Emu
  • Example

AsyncArrowFunction[In, Yield] :: async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBosy[?In] #1

MM: Can I use this standalone?

BT: Sure, but it's just part of Emu

Ecmarkup (Emu)

  • Emu-xref for cross-references
  • Emu-production references
  • Emu-syntax element supports Grammarkdown
  • In use by SIMD, Intl 2.0, Async Function and others
  • Michael Dyck now maintaining es-spec-html, working on high-fidelity emu output
  • Next steps:
  • Unclock authoring of new specs and porting of 262
  • New EMD processing model
  • Continue improving authoring tools
  • Emd 3.0

AWB: note that the Python program that Jason wrote has evolved

Ecmarkdown (Emd)

  • Working towards 3.0 release
  • Hand written parser
  • Support for parsing entre documents (not just single paragraph/list or fragment)
  • Support for more Markdown-like syntax
  • Bullet lists
  • Backslash escape
  • Next steps:
  • Unblock authoring of new specs and porting exsting spec
  • Syntax for links
  • Smart quotes

6.6 BindingRestElement should allow a BindingPattern ala

AssignmentRestElement

(Brian Terlson)

Slides

BT: AssignmentRestElement allows destructuring, BindingRestElement throws. Destructure rest on assignment, but not on binding

  • Historic accident
  • Bug filed on error thrown by having an array lutera after a rest
  • ecmascript#3361

Possible Avenues

  1. Keep as is
  2. Remove support for a bunding pattern in a rest element
  3. Align AssignmentPattern with BindingPattern to allow further destructuring of the rest element

BindingRestElement[Yield] : ... BindingIdentifier[?Yield] ... BindingPattern[?Yield]

Plus necessary statc and runtime semantics to align with BindingPattern

MM: Made and fixed this error in research.google.com/pubs/pub43462.html

  • Any reason to not do the general orthogonal thing?

BT: No

BT: Babel already treats the same

Conclusion/Resolution

  • Align AssignmentPattern with BindingPattern to allow further destructuring of the rest element

6.7 new & GeneratorFunction

(Brian Terlson)

Slides

BT:

Current Semantics:

  • [[call]] this set normally by caller
  • [[construct]] this is a dynamic ReferenceError

Issues:

  • Potentially confusing
  • new doesn't do anything useful

Possible Solution:

  • GenerationFunction doesn't implement constructor, so new throws
  • this is not a dynamic ReferenceError, but instead refers to the GeneratorFunction instance (align with current implementations: Babel, V8, SM)

AWB: Doesn't act like derived constructor, does ave a prototype property that's used to initialize instances

BT: No case where a subclass will always throw

AWB: Body of function is not run as part of the constructor. The body is not a constructor body in the typical sense

BT: Breaks down the this and new behavior, b/c can't use this with new

AWB: The body isn't run as part of the constructor, it's run as "next"

DH: A generator used with new is weird. (giving an example)

function * Thing(x) {
  this.x = x
}

Thing.prototype.sayHi = function() {};

let thing = new Thing("tc", 39);

thing.x // undefined
thing.y // undefined
thing.next();

thing.x // "tc"
thing.y // undefined
thing.next();

thing.x // "tc"
thing.y // 39

DH: Why would want to pause before fully constructing the object?

  • Introduces a non-orthogonality that doesn't pay for itself

AWB: Generator method

let obj = {
  *foo() {
    yield this;
  }
};

let iter = new obj.foo();

RW: Non-generator method would throw a TypeError when new ...

MM/DH: (discussing special cases)

BT: Potential argument for why we should allow this inside generator, observables, where you might initialize this before the first yield (by calling next before handing out your iterator)

AWB: this binding is actually set up when the iterator is created

MM: A generator method, that does not mention super, has a call behaviour that sets this from it's caller the way that a generator function does

AWB: imagine "MyCollection"


class MyCollection {
  constructor() {
    // ...
  }
  * values() {
    let k = 0;
    let length = this.length;
    while (k < length) {
      yield this[k++];
    }
  }
}

let collection = new MyCollection();

let values = collection.values();

class MyCollection {
  constructor() {
  //
  }
}

let collection = new MyCollection();

collection.values = function * () {
  console.log(this);
};

DH: Have a construct trap, normal new object passed in. Generator function is a generator implementation of a function.

  • On us to prove/disprove value

BN: If trying to discourage using new, this may already be the case, since this.next(), this.throw(), this.return() will all throw if called from within the generator, because the generator is already executing

AWB: Cannot re-enter

function * Thing(x, y) {
  this.x = x  // current ES6: throw here.
  yield;
  this.y = y;
}

Thing.prototype.sayHi = function() {};

let thing = new Thing("tc", 39);

thing.x // undefined
thing.y // undefined
thing.next(); // current ES6: ReferenceError on `this`

thing.x // "tc"
thing.y // undefined
thing.next();

thing.x // "tc"
thing.y // 39

(Note that SpiderMonkey doesn't throw at either of the places called out above)

DH: The * is a way of saying that you're providing a way to the precise thing you would do by hand, but without the long form hand written

RW: Then generator method should throw TypeError when called with new

DH: Agreed

MM: What is the instance created from whehn a generator method is called with new?

AWB: instance of Generator

MM:

let coll = {*values() {}};
let it = coll.values();
it instanceof coll.values; // true

MM: Unseen: allocatiing a new generator instance. Contains an implicit new and implcit constructor body.

DH: * imputes an implicit new (in both the method and constructor)

MM: Acting like a function that's calling an implicit constructor

BT: it's a factory

DH: Simpler: "* is never new-able"

Alternative 2: a function * has

MM:

let coll = { *values() { this; } }
coll.values(); // ?

coll.items = function * () { this; };
coll.items(); // ?

DH:

S I Code
? X { *foo() {} } (no [[construct]])
X X function * () {} (no [[construct]])
? ? function * () { this } is exactly like function() { this }

AK (offline): Further spec reading suggests that GeneratorMethods need to have their [[Construct]] removed just like GeneratorFunctions (they both pass "generator" to FunctionInitialize, which is where the decision to set up [[Construct]] is made).

Conclusion/Resolution

  • Maintain spec that cannot construct generator methods (or change spec to make them non-constructible, see above)
  • Spec change: generator function do not have a [[construct]] trap, so new throws
  • Call a generator, this should be set by the caller, as is normal (global or undefined)
  • File Errata

6.12 String.prototype.split, its limit argument, and ToLength vs ToUint32

(Adam Klein)

gist.github.com/ajklein/335e0f948c500a0c25dc

AK: Issues:

  • ES5 (15.5.4.14.5): If limit is undefined, let lim = 2**32-1; else let lim = ToUint32(limit).
  • ES6 (21.1.3.17.8): If limit is undefined, let lim = 2**53-1; else let lim = ToLength(limit).

Problems:

  • Return value is an Array, so a limit greater than 2**32-1 would result in a "malformed" array (one with elements past the end of the array). Iteration over the return value will skip all such elements.
  • Behavior changes for negative limit: ToUint32 transforms -1 to 232-1; ToLength instead transforms -1 to 0.

AWB: One of the discussions was to change arrays to be larger

AK: That would make sense

Discussion about changes

  • break web?
  • but this will never likely be hit by any real world code
  • clamping is valued

Proposal: Revert this spec change. Existing implementations still match ES5, and the old behavior still makes sense (even with ES6's longer String length limit).

WH: The spec needs a geocities-style "Under Construction" animated GIF here ;). This was the first phase of a series of changes attempting to move the spec to eliminate the 2^32 array length limit, with the changes spread over time.

Conclusion/Resolution

  • Revert this spec change. Existing implementations still match ES5, and the old behavior still makes sense (even with ES6's longer String length limit).
  • Filed ecmascript#4432
# Rick Waldron (9 years ago)

(Slides are at tc39/tc39-notes/tree/master/es7/2015-07 )

July 29 2015 Meeting Notes

Allen Wirfs-Brock (AWB), Sebastian Markbage (SM), Jafar Husain (JH), Eric Farriauolo (EF), Caridy Patino (CP), Waldemar Horwat (WH), Istvan Sebastian (IS), Mark Miller (MM), Adam Klein (AK), Michael Ficarra (MF), Peter Jensen (PJ), Domenic Denicola (DD), Jordan Harband (JHD), Jonathan Turner (JT), Paul Leathers (PL), Chip Morningstar (CM), Vladimir Matveev (VM), Ron Buckton (MS), Brian Terlson (BT), Alan Schmitt (AS), Ben Newman (BN), Mohamed Hegazy (MH), Abhijith Chatra (AC), Tom Care (TC), John Neumann (JN), Dave Herman (DH), Brendan Eich (BE), Daniel Ehrenberg (DE), Dan Gohman (DG), Andreas Rossberg (ARB), Rick Waldron (RW), Mike Pennisi (MP), Akrosh Gandhi (AG), Jonathan Sampson (JS)

6.11 The scope of "use strict" with respect to destructuring in

parameter lists

(Andreas Rossberg, on phone)

Slides

ARB: Strictness Scoping

Issues:

  • VMs need to do parsing & static checks in single pass
  • w/o building an AST (lazy compilation)
  • Backtracking is not an option (at least not for V8)

DH: clarify backtracking (2 possibilities?)

ARB: rewinding token stream

ARB: easy in ES5 because only additional check is duplicate parameter names

"use sloppy";
function f(x, x) { "use strict"; }

Difficult in ES6, b/c default parameters

"use sloppy";
function f(g = (o) => {with (o) {}}) { "use strict"; }

ARB: also cannot determine scope due to interactions between Annex B and strict mode:

"use sloppy";
function f(g = function(h) {
  { function h() {} }  return h;
}) {
  "use strict";
}

WH: The issue in this example is hoisting and variable binding, which is more than just error checking. Function h here is nested inside a local block, which means that the 'h' in the return statement refers to different bindings in strict vs. non-strict mode. But you don't know that strict mode is in effect until encountering the 'use strict' later!

DH: Don't know yet whether this is an error until later. Previous examples: Store a "dirty bit". This example: have to have a data structure that will hoist in 1 of 2 ways if it turns out to be strict mode. Implementable without backtracking.

WH: Note that a single state bit is insufficient. You can have these things nested arbitrarily deep, leading to a potential exponential explosion of states.

ARB:

Much More Difficult in ES6

  • The directive can affect arbitrary code
  • Nested arbitrarily deep
  • Would need ot defer any sort of mode-specific decisions in the parser for code that occurs in parameters
  • But with arrow functions, we do not even know (in time) that we are in a parameter list
"use sloppy";
let f = (g = () => { /* Are we a parameter? Do we have to defer? */ with
(o) {} }) => { "use strict"; }

ARB:

BE: The arrows are parsed with a cover grammar

  • When initially implementing strict mode, SpiderMonkey had to implement token stream backtracking to account for the function body "use strict" prologue affecting to the left

ARB:

Categories of mode specific logic

  1. Mode-specifc errors: (eg. with, delete, for-in, octals, let, variable name validity, parameter conflicts) -> Easy to defer, at least in principle, but may have measurable cost

  2. Special handling of eval (scoping, variable modes) -> Not an issue

  3. Actual divergence in parsing/scoping (Annex B function scoping, yield?) -> Affect downstream decisions, transitively defer

DH: yield doesn't have contextual differences in strict mode, in generator functions

AWB: restricted in strict mode (non-generator) functions

  • other differences?

DH: this-binding

YK: to be clear, these disadvantages only apply to sloppy mode programs; modules and strict mode programs are not affected

ARB: 3 modes, effectively:

  • sloppy
  • strict
  • "don't know"

DH: (discussing potential for performance regression)

  • Any parenthesis expression could potentially end up in slow mode

ARB: Agree

AWB: Don't see this as a problem for JITs

BE: (asks implementors what they're doing to solve)

  • SpiderMonkey uses token stream rewinding and it covers all the cases

PL: We haven't gotten this far

ARB: This has been brought up with the team before, and token stream rewinding has been off the table

  • Don't want to do token stream rewinding in V8, various issues (e.g. with Blink interaction?)

BE: If it can be done and satisfies performance constraints, then engines should consider

ARB: Compiling functions separately, ie. if function in parameters, compile sep. More than just rewind, would have to record all the functions, may be done with them, may not be done with them

MF: Can we see a proposal/solution?

ARB: Make it an error to have a "use strict" directive in a function with a non-simple parameter list.

YK: Should implement ES6 as written while this is resolved.

  • Don't block implementing default parameters on this
  • Just a suggestion

BE: "more of a guideline than rule"

AWB: You could make the restriction more specific: only disallow functions that declare "use strict" and contain a function in their formals list

ARB: Could be that only error when "use strict" inside function would change the mode, as the outer mode might already be strict

YK: refactoring hazard.

BE: Jason Orendorff says "works for me"

AC: don't like this suggestion, I don't want to impose an error because an implementor couldn't make it work

Discussion, re: hardship of implementation

YK: Don't like that end developers have to know why this won't work, b/c implementing hard.

BE: implementors are considered second to developers

AWB: previously, sloppy mode was restricted to simple parameter lists.

BE: No micro modes: no runtime semantic differences due to

AC: Chakra implements with rewinding

YK: objection: semantically this is the wrong thing

DD: but we're moving to all-strict world, so making the mixed mode cases more painful might be ok

DH: This is such an edge case that I don't tihnk there is an adoption risk.

  • "use strict" retroactively providing subtle differences in the parameter list is a gotcha
  • preventing diversions in the semantics to close window of confusion

BE: Suggestion fixes the right-to-left violation

DH: Could enumerate all those cases and make errors, but much harder.

  • Fixes, but means new rule

YK: Poisioning function () { "use strict" }

BE: use top level "use strict"

YK: Not realistic

BE: Andreas reduced list to parameter lists that contain:

  • functions
  • arrows
  • future "do" expressions

Discussion re: "use strict" expectations

YK: Prefer the stricter rule

DH: appear to have consensus on Andreas' solution

AWB: What exactly do we mean by "a function with a 'use strict'; prologue? Are we only talking about "strict transitions" (i.e. functions that declare "use strict" that are in non-strict contexts) or do we mean "use strict" in any functions.

MM: Functions that have a "use strict" know that they are strict, whether they are "pasted" or typed

  • Taking the strict function out of strict context may cause errors as a result of code execution that previously expected strict context, which is a refactoring hazard

MP: Another (less difficult/serious) case where strict-function-rewinding is relevant is in the case of named function expressions. e.g.

(function static() { "use strict"; });

Ref: ecmascript#4243

Discussing implemention strategies

  • checking for duplicates
  • eval, arguments
  • yield, let

BE/AWB: existing semantics imply some right-to-left checking

BE: Non-simple is:

  • default
  • destructuring
  • rest

(Anything that is not a list of identifiers)

YK: Need to acknowledge that we'll need to tell people to not "use strict" in functions, if they use non-simple parameters.

Acknowledged.

The solution is just use top level "use strict"

DH: We'll fail to explain this at the level of enumerating ES6 features they can or can't use in this case. The outcome is something like "just use top-level strict, or iife strict"

  • Would like to revisit

YK: Not just this edge case: ES6 and strict mode has created this weird window.

AK: Functions in the parameter list might become strict if the function is "use strict"

DH: this behaviour changes

YK: Ultimately breaking "use strict" for function

AWB: Any function whose mode (lost track)

Discussion about ES6 feature adoption.

RW: disagreed with error when "use strict" occurs locally, but outer mode is already strict (ie. no mode change)

Discussion about developer expectation.

AWB: there is another alternative spec function that is more restrictive: ContainsExpression

RW demures ("You might say I am not willing to die on this hill.")

Conclusion/Resolution

6.9 Reconsidering the Number.prototype-as-an-ordinary-object change

(Daniel Ehrenberg)

DE: This change breaks the web (specifically: mootools calls Number.prototype.valueOf(Number.prototype))

esdiscuss.org/topic/number-prototype-not-being-an-instance-breaks-the-web-too, mootools/mootools-core#2711

Solution: roll back the change.

BE: Number, String, Boolean should be

MM: To be clear: Date.prototype will be an object, not Date; RegExp.protototype will be an object, not RegExp. Every built-in constructor introduced after ES5 will have a plain object prototype.

MM: Prefer we do Number, Boolean, String together

Conclusion/Resolution

  • Boolean.prototype, Number.prototype, String.prototype rolled back
  • File a spec bug?

6.12 Spec defacto String.prototype.trimLeft/trimRight

(Sebastian Markbage)

sebmarkbage/ecmascript-string-left-right-trim

SM: Already shipping in all major engines. Controversy: what to call it?

JHD: in JavaScript, left-to-rightness of strings is a rendering artifact. The conceptual "first" character of any string, whether LTR or RTL, is index 0, and the "last" is index length minus 1. Thus, in JS, left/start/index zero are the same, and right/end/index length minus one are the same.

DH: These are extremely common in programming languages

Discussing semantics of "left", "right" and "start", "end"

DH: There is precedence for JavaScript interpreting the word "right" to mean "the end of a sequence", from ES5: Array.prototype.reduceRight

Conclusion/Resolution

  • Approved for Stage 1?

REVISIT: 6.11 The scope of "use strict" with respect to destructuring in

parameter lists

DH: The only thing that "use strict" can cause (in ES5) is an error (to the left)

  • Our resolution was to say, "the use strict prologue in functions is now defunct"
  • An alternative, w/ better outcome: revise "use strict" to no longer affect anything to the left.
  • A back-compat change, because it only allows things that were previously disallowed.
  • no semantic difference

AWB: There are implementation semantics, w/r to parameters

  • extra scope contour for eval context
  • duplicate parameters

WH: How does it affect hoisting checks?

AWB: Hoisting rules in annex b don't apply if there is decl of same name (need to double check)

MM: How did we resolve names introduced in the function head vs names introduced in the function body, w/r let/const

AWB: disallowed

Discussion, re: strict in blocks?

AWB: need to check this against the existing function declaration instantiation, re: strict/non-strict checks

STH: Expressions in parameter list are not in strict mode.

  • Enter strict mode due to prologue at beginning of function, does put parameter list expressions in strict mode

YK: Bigger picture: ES5 introduced the concept of a strict function.

  • The proposal before is honest about admitting that's not a thing
  • Sam's proposal ignores that and introduce's a new thing

Discussion, re: expectations of strict mode in functions

AWB: parameter with an initializer that uses this

  • Assuming that's called with nothing in that position, what is this?
  • If strict, this is undefined
  • If sloppy, this is global object
"use sloppy";
function f(foo = this) {
  "use strict";
  return foo;
}
f();
// what is the value of this expression? the global object? or `undefined`?
// w/r to Sam's proposal (eliminating right-to-left strict-ness effect)

YK:

With Sam's proposa, this would return [undefined, Global], despite expecting [undefined, undefined]

(function(foo = this) {
  "use strict";
  return [this, foo];
})();


DH: In ES5, there was a fundamental confusion about "use strict" in
functions. This was excacerbated by es6. In the fullness of time, TC39 is
saying, the directive prologue should be used:

- Global "use strict" (being careful of script concatenation)
- Top-level IIFE "use strict"
- module code

MM: We should be explicit w/r to "top level strict mode", in that we
actually mean "top level iife with strict mode"—to avoid the concatenation
problem.

Advice: "Just use modules".

#### Conclusion/Resolution

- The previous consensus remains




## REVISIT: 6.7 new & GeneratorFunction

AWB: (answers to questions from yesterday)

- Generator functions are new-able
- Generator methods are new-able
- Implicit body


```js
function * g() { this.foo }

x = {
  *f() { this.foo }
};

new f(); // ok
new x.f(); // ok

Relevant SpiderMonkey bug: bugzilla.mozilla.org/show_bug.cgi?id=1166950

DH: Bare generator function call behaviour is correct?

AWB: Confirm

Updated:

S I Code
X X { *foo() {} } (no [[construct]])
X X function * () {} (no [[construct]])
? ? function * () { this } is exactly like function() { this }

AWB: Concern about removing new:

  • Implemented to allow it without throwing
  • No TDZ on this

Acceptable risk?

BT: Implementors on both V8 and SpiderMonkey have shown interest in making generator not newable

Conclusion/Resolution

  • Spec change: generator functions and methods do not have a [[construct]] trap, so new throws

Process Document discussion (to settle things once and for all)

(Domenic Denicola)

DD: (Showing tc39.github.io/process-document)

Reviewed:

AWB: w/r to reviewers, committee should assign reviewers.

DD/RW: reviewers attached at Stage 1. Stage 2 entrance requires review

RW: Propose: At Stage 0, reviewers get "attached", but non-binding. (basically, it's a "champion group")

... Next thing...

What is an "implementation"?

Discussion re: Stage 4

  • Important to get feedback from engaged implementors

RW: Concerns about flag/no flag

DD: Must be unflagged

RW: Disagree, will result in stonewalling from implementors

DH: Transpilers should count

Discussion, re: experiences had with other new features.

"Significant in-the-field experience with shipping implementations, such as that provided by independent VMs"

Stage 3: "Will require feedback from implementations and users"

Conclusion/Resolution

  • need links to Domenic's commits

6.8 SIMD.js: Start the process to move towards Stage 3

(Dan Gohman, John Mccutchan, Peter Jensen, Daniel Ehrenberg)

Slides

DE: (introducing topic)

  • Boolean vectors Previously, the result of SIMD.Float32x4.greaterThan was a SIMD.Int32x4 vector, with -1/0 for true/false Now, new boolean vector types, e.g. SIMD.Bool32x4, represent boolean results and values Used for select and logic operations More efficiently implementable on some architectures Not simply Boolx4 because the registers in implementations may be represented differently based on width.

  • Unsigned operations

Unsigned comparisons Unsigned saturating add/sub Unsigned extractLane No changes needed for constructor, replaceLane because coercion will wrap unsigned values to the appropriate signed value No separate unsigned type

  • Postponed features

Float64x2--we couldn’t find an important use case with improved performance Int64x2--Not needed due to boolean vectors, and really not needed because Float64x2 is out selectBits--minimal utility due to select, and efficiently implementable in terms of other boolean operations

  • sumOfAbsoluteDifferences replacement

widenedAbsoluteDifference, unsignedHorizontalSum, absoluteDifference Seeking implementation feedback: applications and benchmarks Replaces sumOfAbsoluteDifferences (slow on ARM)

  • Other spec changes

Homoiconic toString() SIMD.Float32x4(1, 2, 3, 4).toString() => "SIMD.Float32x4(1, 2, 3, 4)"

Shift operations max out at 0/-1, rather than wrapping around Ops like reciprocalApproximation are loosely specified, like Math.sin Removed operations on DataView--TypedArray ops suffice Operations on subnormals may flush to 0, unlike ES scalars Various minor spec bug fixes

AWB: w/r toString. The approach shown is a new precedent

DD: Similar to Symbol

AWB: Will this be the new way

BE: value types with literal form should convert, but this isn't value types. I like it.

AWB: Should other new things have this toString() output? Map & Set?

(moving on)

  • Strong type checks on lanes

Lanes are required to be Int32s and not implicitly coerced

(See 5.1.2, littledan.github.io/simd.html )

AWB: for WebIDL, we advised to use normal ES coercions

DE: Considered specified getX, getY, etc.

DH: I don't know if it's that important to coerce or check.

BE: Doesn't want this to be an enumerated type. Symbols?

AWB: The advantage is that Symbol is not coercible and you only accept those that you've defined.

DE: if we had a Symbol API, we'd still want an extract lane API

STH: numbers are the right thing here

AWB: ToNumber, because that's what ES does

  • Actually ToInteger
  • ToLength

WH: Note that the proposal is a bit inconsistent in validating numeric inputs. For example, shifts use ToUint32 for the shift count, which turns -1 into a huge shift amount. ECMAScript's built-in shifts treat the shift amount mod 32, while the proposed ones treat it mod 2^32.

DE:

  • load and store operating on any TypedArrays

load and store take TypedArrays as arguments and permit array element type mismatch with SIMD type

WH: Reading spec, cannot load and store booleans. Looks intentional.

DE: Fails on booleans, intentionally.

  • Intentionally abstract data type
  • Want concrete data type, call select

WH: Fix other places in the spec for booleans, such as the statement that bitwise cast can cast any SIMD type into another SIMD type.

AWB: (requests justification for extracting values of a different type than the type of the Typed Array)

DE: DataView doesn't really work, in an asm context. Operations on DataView accept endianness where this has to use native endianness to be efficient

AWB: if int8 array, extracting floar 64, does it

DE: No, it is element-aligned. The hardware supports this.

DG: (phone) confirms hardware support

AWB: If you're talking about a float32array and you're extracting int16's, that just seems like a type error.

DE: Better?

DH: Go back and change array buffer, can't do that

  • ArrayBuffer was defined as opaque
  • Everyone wants to change rthat now
  • No real world constraint

DE: how is opacity enforced?

(no answer yet)

WH: Some ArrayBuffers are indeed opaque. Restricted exposure for security reason

DH: TypedArray views on ArrayBuffer, detached

  • Allow operation on ArrayBuffer
  • We'll have to break the invariant

BE/DH: what they're doing will work

WH: Not a pointless invariant. Move on.

(moved on)

Questions for Committee

  • Should wrapper constructors be explicitly [[Construct]]-able, like Number, or not, like Symbol?

BE: have to call with new to get the object

AWB: Symbol is just odd because concern that new Symbol() would be used to get a generative object.

DD: Necessary to impose a rule for creating a Symbol

  • No literal form? No wrapper

DE: if you call construct, if NewTarget undefined, construct wrapper

AWB: Minimize new patterns. Overloading constructor is not new.

AK: Why this route instead of Symbol route?

DE: Symbol is special throwing on new? But maybe Symbol is the new way

DD: If no literal, then no new. If a literal is added later, then re-open new

BE: (explains wrapper history, aggree with DD)

(moving on)

Spec Language Innovation Acceptable?

  • Rest parameters
  • SIMD as a spec meta-variable

AWB: There was use of rest early in ES6, but taken out

BE: parameters that were optional

AWB: implies JS level parameter list

DE: no

Discussion, re: spec mechanisms

(moving on)

RW: Recommend moving this to a separate spec, similar to Intl (Ecma-402). (Note that this was considered ideal by the champions as well, despite the opposition from other members).

DH: disagrees

WH: Also disagrees with separate spec. This defines primitives tightly bound into the core of ES, with serious interactions and precedence-setting with other ES work such as value types.

DE: Issues surrounding value type definitions, but don't want to to wait for value types. Don't want to be blocked and separate spec ensures that

(moving on to implementation status)

Firefox Implementation Status

In Firefox nightly:

  • Float32x4 and Int32x4 entirely implemented and optimized in JavaScript (regular and asm.js) on x86 and x64.
  • Missing boolean vectors
  • Other SIMD types (Int16x8, Int8x16, Float64x2) partially implemented in the interpreter only (ergo not optimized). The newer APIs (SAD) haven't been implemented yet.
  • All SIMD types are implemented as value objects, at the moment.

Microsoft Edge Implementation Status

  • Majority of SIMD.. APIS supported.
  • Some of the new APIS need to be implemented such as ExtractLane and ReplaceLane, and unsigned operations
  • Asm.js optimization is complete (minus new api support).
  • Non-asm.js optimization we plan to start soon.

V8 Implementation Status

  • Intel object implementation will not be used for V8 and work has started to implement value types from scratch. Intel code generation may be rewritten to the new model.
  • Bill Budge has added a Float32x4 type with correct value semantics and basic operations, without acceleration, behind a flag.

Specification Status

  • SIMD.js Specification v0.7.2
  • Updated polyfill and tests validate all operations, basic value semantics
  • SIMD.js is ready for reviewers and and editor comments/signoff
  • Hope to move to Stage 3 in the September meeting

Requesting reviewers

WH: purpose of spec, disagreement whether to support only use cases experienced or useful with a more ecmascripty orthogonal feel. For example, the spec currently can load int8, uint8, int16, uint16, int32, uint32, but it can only extract the first five of them (can't extract uint32 even though can extract int32 or uint16). Min and max work on floats but not on integers, even though there is no hardware obstacle to do so and even though there are much more complex intrinsics defined such as unsignedAbsoluteDifference.

DE: support unsigned operations on int16 and int8

BE: waldemar wants max on integers that can

DH: SIMD building clear layer to hardware

WH: want consistency:

  • integer max
  • uint32
  • for usability, uint8 SIMD pixel values printing liked TypedArrays as 255,255,0 instead of -1,-1,0.

WH: Diverged from TypedArray,

AWB: TypedArray both have int32 and uint32, JS programmer expects that

BE: argument to be consistent

DE: TypedArray is the model going forward, with the exception of Uint8ClampedArray

AWB/BE: Yes

WH: treatment of denorms non-deterministic

DE:

  • operation and flush to 0
  • operation only

WH: Does the hardware flush both inputs and outputs to 0, or is there some major hardware that flashes only inputs or only outputs to zero? (an arithmetic operation might take denorms as inputs, or it could produce a denorm output even though all inputs are norms)

DE: Both inputs and outputs

WH: [later in the discussion] Intel has FTZ and DAZ bits which control these separately, so they can be independent.

(Difference between Arm and Intel)

DG: Arm 64, arm v8 corrects this

MM: this non-determinism is actually just difference between platform

WH: The SIMD spec doesn't state that. It could differ operation-by-operation.

DE: The spec can't state that.

WH: Really? Why?

Discussion re: nan encoding

DE: www.ecma-international.org/ecma-262/6.0/#sec-setvalueinbuffer (step 9.a)

AWB: (explaining why spec says this)

DH: we should change the def of SameValueZero to say that two different bit patterns for a NaN are not equivalent

DE: create a data property and set value to one bit pattern, non-writable, non-configurable, call Object.defineProperty with a different NaN, then do [[Get]] and you'll receive old bit pattern

DH: No mutation, but incorrectly states that change was successful

DE: spec says a platform will have one endianess or the other; this can be applied to denorms. Spec dependent.

WH: What do relational operations (.equal, .lessThan, etc.) do when they see a denorm? treat as zero?

DG: treat as zero

WH: So then what will === do? Do they equate all distinct denorms to zero (which would be really weird as ES behavior)? Are you going for the fast implementation of === or the precise implementation?

DG: === does not equate denorms to zero, even on platforms that flush denorms. It can be slower than .equal.

ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4610935

DE: One outstanding question was whether this work should be done in a separate specification.

RW: Yes, I had suggested that. But you said something about a polyfill for SIMD.js?

DE: It is incomplete

BE: It can't express value object; it can't intercept == or ===

RW: Alright, then it is no longer a suggestion of mine

Unsigned Types? Argument for them?

Consistency with TypedArray

DH: I want to know more about what SIMD use cases are, operations should map to need

WH: want unsigned types:

  • consistency with typed array
  • printing (want 255, not -1)

(not an explosion of the API)

DE: fewer function names, more function objects.

AWB: lot's of domains with similar conventions

  • once integrated, it becomes part of the spec as a whole and will require understanding of these irregularities
  • an argument for separate spec

DE: it's a large thing, mostly irreducible

JHD: non-specialists are going to write this stuff by hand.

(Argument to make the API more like JS)

DE: prefer to keep it as is

YK: So a specialist doesn't need the unsigned types?

  • then don't worry about use by non-specialists

DH: Either accept Waldemar's argument, or state case based on historical precedence. If no consistency, then don't care.

WH: Note that I'm not alone with that argument. I don't want this to become personal.

Conclusion/Resolution

  • new throws
  • not separate spec
  • spec mechansisms: Allen, Brian, Rick and Dan to work through
  • Reviewers:
    • Waldemar Horwat
    • Jordan Harband
    • Brendan Eich
    • Mark Miller
# Rick Waldron (9 years ago)

(Slides are at tc39/tc39-notes/tree/master/es7/2015-07 )

July 30 2015 Meeting Notes

Allen Wirfs-Brock (AWB), Sebastian Markbage (SM), Jafar Husain (JH), Eric Farriauolo (EF), Caridy Patino (CP), Waldemar Horwat (WH), Istvan Sebastian (IS), Mark Miller (MM), Adam Klein (AK), Michael Ficarra (MF), Peter Jensen (PJ), Domenic Denicola (DD), Jordan Harband (JHD), Jonathan Turner (JT), Paul Leathers (PL), Chip Morningstar (CM), Vladimir Matveev (VM), Ron Buckton (MS), Brian Terlson (BT), Alan Schmitt (AS), Ben Newman (BN), Mohamed Hegazy (MH), Abhijith Chatra (AC), Tom Care (TC), John Neumann (JN), Dave Herman (DH), Brendan Eich (BE), Daniel Ehrenberg (DE), Dan Gohman (DG), Andreas Rossberg (ARB), Rick Waldron (RW), Mike Pennisi (MP), Akrosh Gandhi (AG), Jonathan Sampson (JS)

7 Test262 Updates

(Brian Terlson, Mike Pennisi)

Slides

MP: Introduction

See slides

WH: (re: jugglinmike.github.io/presentations/2015/tc39-test262-update/#7 ) question, re: es6draft, ecmascript spec, before/after publication?

?: es6draft ? ECMAScript 6 draft

BT: Ongoing. Could also add Chakra bugs

MF: raw flag? Does this prevent issues other than directive prologue issues?

MP/BT: "raw" means: don't touch the file, just run it. No access to assert features, useful for syntax only tests

[discussing distinction between early errors and parse errors that test262 does]

jugglinmike.github.io/presentations/2015/tc39-test262-update/#12

AWB: These are a specification artifact. An implementation doesn't have to do parsing and early errors in separate passes.

WH: This becomes visible when there are multiple errors, some in parsing and some early errors. Does the spec designate which error should be reported when there are multiple of these?

AWB: No. An implementation is free to report any of these errors.

AWB: Distinguishing early and parsing errors in tests is overspecifying.

(re: website improvements)

BT: current test262 site does not have ES6 collatoral.

  • Implementing ToLength appears to lock up the website
  • Alot of work needed to get the test262 site into a functional state
  • Is the work something that Bocoup is going to do?

MP: Nearing end of time, but ideally would like to take on this work

BT: Then we need to find a "resource" for this project

  • Enumerating outstanding issues with test262 website

YK: Considered running tests in iframe or worker and timing out?

BT: Harness uses iframes

Discussion of implementation details of test harness

BT: Requirement of new site: use web workers

Moving on to jugglinmike.github.io/presentations/2015/tc39-test262-update/#15

MP: (first example) TypedArray, 9 sets of the same tests. The tests might start in sync, but it's hard to maintain over time.

  • Typed Arrays (9)
  • Destructuring Assignment (3)
    • AssignmentExpression evaluation
    • ForIn/OfBodyEvaluation
      • for..in statement
      • for..of statement
  • Spread Operator (4)
    • ArrayLiteral: [...x]
    • ArgumentList
      • SuperCall: super(...x)
      • CallExpression: f(...x)
      • MemberExpression: new f(...x)
  • Expressions & Declarations
    • Function
    • Generator
    • Class

AWB: Similar to wanting to share code in tests, implementations will want to share code.

  • Look at how an implementation and its tests go wrong?
  • Tests that would catch the most common ways the implementation abstractions might go wrong

YK: Instead of testing all the things, find the things that might fail

  • things that look similar, but are subtley different: test that.

MP: (gives an example of how strict and non-strict tests are automattically run, unless flagged)

WH: Value in testing exhaustively when the number of cases is reasonable. Per the presentation, there are only 18 contexts in which destructuring is used, which is reasonable for full cross-product testing.

  • Re: Allen's point, there are subtle things that can go wrong. I can imagine an implementation getting destructuring right in most contexts but messing up some subtle aspect of it for, say, arrow function parameters.
  • But still worthwhile to test try to be exhaustive

BT: Not suggesting that we won't test syntax in unique contexts

  • More about the authoring
  • For tests that cover identical syntax semantics and the only difference is syntactic context, then test once
  • Why not sweet.js or an existing templating engine? We need to test syntax errors (and other negative tests)

WH: Just pick one that doesn't make you escape all of the ECMAScript syntax

Discussion, re: gist.github.com/jugglinmike/476bdb6dd69ffddaf9d2#syntax

AK: (concerns about useful output)

DD: most consumers clone the repo, so we need to make sure that we check the output as well

AK: I'm less concerned about running, but about the output that will inform me of the failure

BT: Don't want to check in the actual generated tests

  • This proposal MUST make it easy to identify failures
  • The test harness will write to disc the actual code that failed at the moment of failure
  • produce, on-demand, the filled-in template

DE: For tests users, this can be automated?

BT: Yes.

Conclusion/Resolution

  • Continue exploring test generation

Meeting Schedule

(John Neumann)

JN: will propose a 2016 schedule in september. Need to know if we'll be in Europe?

  • Switzerland: Geneva, Lugano, Montreux, Lausanne (Geneva may not work: too many attendants and too expensive)
  • Germany: Munich
  • France
  • England

Discussion planned for next meeting

  • September in Portland, hosted by jQuery/Yehuda
  • November in Santa Clara, hosted by PayPal

JN: Need to confirm what the 7th edition will contain

YK: Straight forward, whatever is Stage 4 goes in the spec

AWB: (enumerating general spec process timelines)

  • submission
  • review
  • 60 day opt-out

YK: That's after January?

AWB: Approximately end of January

YK: January is submission, work backward to find deadline.

Discussion re: time needed for Brian to integrate the stage 4 features.

Conclusion/Resolution

  • Get proposals wrapped up if you want to get these features into the spec

6.4 Advance Async Functions to Stage 2

(Brian Terlson)

Slides

BT:

Updates from Last Time

DH: Future proof for potential future syntax extensions

DD: Clarify not await *

BT: await * was not useful. If there is a proposal for a useful semantics, then good, but not in this proposal.

Questions

  • Async Arrow Function
    • async (a, b) => await a + await b;
    • (a, b) @=> await a + await b;

DE: What's the issue with the first?

BT: async not a keyword and that could be a call: async(a, b)

MM: @ seems like a poor choice, but I don't have an alternate suggestion

AWB: only b/c "a"sync

  • the async form defeats the conciseness

BT: I've worked out the grammar, it needs review, but it appears to work correctly

YK: Shouldn't have 3 sigils right next to eachother.

  • hard to google a sigil or set of symbols
  • a "grawlix" problem

BT: Opposed with the top grammar? (assuming the grammar works)

(no opposition, pending review)

DH: Would like to see more code illustrating actual use cases

DD: There's a lot of code in the wild that's been using the top form

DH: Any higher order combinator is where this will have the most use.

MM: No consensus on the second. Consensus on the first contingient on grammar validation

DH: Cannot make async a keyword, one of the most popular modules on npm is async

DD: Promise.all doesn't quite work because it's a combinator that takes promises, not functions that return promises

DH: The syntax that we've come up with for past features like => map to

an extremely high use case with hardship. Not clear to me that we have the full async callback picture

DD: should look into the ecosystem of Babel users and see where it's come up

Design Questions (continued)

  • Newing an async function:
    • Error
    • Promise-for-instance

BT: Suggest "no" (no disagreement)

Design Questions (continued)

  • Errors in Parameter Initialization
function* foo(a = (function() { throw 1; }())) {

}
let iter = foo(); // throws 1

BT: the equivalent in async functions:

async function bar(a = (function() { throw 1; }())) {

}
bar(); // as of the latest proposal, this throws 1

// Alternative semantics would have the error deferred:
bar().catch(cb => ...); // Possible semantics

DD: Wish this was caught for generators

AWB: We knew about it, but nothing can be done

MM: For generators, we have immediate throw

  • Async function: throw in body breaks the promise
  • think about when the throw happens
  • what way is it reported?
  • throw in generator body is reported with a throw
  • throw in async body is reported by rejecting promise

YK: when use promise, you can catch all the errors into one place

AK: Arguing for throw immediately?

BT: Yes, found that error throwing default parameters don't happen (rare case?)

  • Mark's point about multiple symmetry in play

CM: setup preparation part, consumption part. The generator setup might have error in setup, reported immediately

DD: Code will expect to receive the error via the catch path, not an immediate throw path.

  • Most promise ops go through the API
  • Devs can muck with the built-ins and produce errors

AWB: What if you put a proxy on an async function and the call trap throws?

MM: There's not a problem with the [[Call]] trap. If the [[Call]] trap in the Proxy throws, then you have a "throw".

AWB: Say the async function is actually a proxy wrapped around an async function?

MM: It's exactly the same hazard as if you hand someone a function that wraps an async function and the wrapping function throws.

DD: Problem is thinking of async functions as a separate category. Just a function

DH: Mark, I agree. There are errors we consider normal to happen in programs that you should deal with, and those where soemthing went badly wrong and you can't write code that has try/catch every where. A function call that throws an exception should follow the error handling model for the programming paradigm that we're in; since we're in an aync world, the programming model for handlng errors is catch

BT: want to be very clear about rationalization, so that same can be applied to async generator.

AWB: The generator function returns its value before evaluating its body.

  • A generator is a function

MM: An async generator... I missed the rest of this

YK: Can you yield in a default parameter in a generator?

AWB: No, you cannot yield there because the object doesn't exist yet.

BT: We need to establish the rationale for the behavior of error handling in non-simple generator parameter lists

YK: Might've been a mistake?

AWB: Generators do what generator functions previously did in Firefox. We weren't sure if it should be changed. Different results:

  • timing evaluation changes: happen on the first next, the values aren't the same values at the time of the call.

DD: Generators suspend immediately, async suspend on the first await

DH: All cases, expect that parameter default expressions execute eagerly, not that they execute at some time later

DH: Generators are all about order of execution. The fact that generator functions and async functions have different control flow expectations means that it's reasonable for their error handling behavior to differ.

Discussion about complications of the implicit yield in generators

DH: Don't need symmetry between generator and async

YK: Async function is just a function, but the generator is a different thing.

  • When calling a generator, you're not calling a function as shown

DD: When calling a generator function, the first line of the function does not execute

DD/YK: Agreed.

YK: The consequence is that the refactoring doesn't make sense.

Design Questions Continued

  • Await synchronous things synchronously
    • await 1 does it trigger a turn of the event loop as in the desugaring?
    • allow synchronous await but ensure promise resoltion is async?
    • do neither and allow returning an already-resolved promise?

MM: describing the hazard of sometimes "sync" and sometimes "async"

????????????????Z??????????A???????????L????????????G????????????????????????? !????????????

:applause:

YK: The same hazard doesn't exist with await, because the callback model is changing which scope the function is called in, but doesn't exist in await.

MM: Agreed that the hazard to aync functions is smaller than that to Promises. The bugs will be both fewer and more subtle and harder to figure out.

DD: no cost to go back to the event loop

YK: not true.

  • hot code is always awaiting some promise, could be optimized to consider inline-able. Never true if you always have to go back to the queue

MM: If an implementation can optimize, which is very hard and hazardous

YK: I'm making a different point. If you say. "you are not allowed to go back to the event loop" and if you discover that it is synchronous, then you can optimize by in-lining the synchronous code. In an ideal world, it is "just a loop", and a loop is fast.

JH: The relative harm: cost not zero, need to weigh

MM: Experience with asap, cost is worth it to reduce the hazard.

  • When bugs do occur, very subtle and hard for programmer to figure out

YK: Hazard in the callback case is in pieces of code that are right next to eachother that appear to [...] Let me put it another way: the hazards you are talking about are based on assumptions that I would never make when writing a program.

MM: hazard as soon as mutated state is sufficiently non-local

YK: cannot rely on what interleavings are possible

BT: hazard here: order of your next turns change. not that callback could be async, but that your callbacks mayb run out of order. What Yehuda is saying is that people don't write programs with multiple Promises where they expect the promises to resolve at specific turns of the event loop.

MM: Two different hazards:

  • The order of events on the event loop is one hazard
  • the isolation of side effects is job that was executed up to the await point, completes before any code of the await
    • All invariants storing during the job

Mark, I need you to fill this in, we're moving too fast.

YK: Transaction committed before any await is called. This exists in Ember.

  • Need to see an example of the invariant Mark is describing

MM: After the await point, the callee is starting with a fresh stack.

  • Event loop programming paradigm that suspends an invariant must restore the invariant before the job ends.
  • Illustrates with example of doubly linked list operation

MM: Event loop concurrency requires restored invariants before the end of the event loop turn

YK: Different from what's encountered in practice

DD: What's the position?

YK: Discussing already-resolved-promises

DD: await 1 is not the same as await Promise.resolve(1)

  • If you have a promise, you've said that the value is async and breaking that is crazy

MM: Found with the Q.asap bug: I wrote my code, tested my code, then my code had bugs. Result of code running out of turn with test code.

YK: consistency is absorbed by syntax

MM: disagree

  • The bug was directly the result of assuming the invariant will be resolved.

Discussion re: invariant restoration on event turn completion

// BT:
foo().then( function() {
   /* 1 */
});
/* 2 */
// Which is first

async funcion foo() {
  /* 1 */
  await x;
  /* 2 */

  // are these the same turn?
}
foo();
// HAZARD: setup state required by /* 2 */

Currently, await is always async.

JH: Concern that the notion of asynchrony bound to...?

MM:

JH: predicts that await means async to developers. await is composition.

DD: yield is composition

MM: asynchrony is mandated by the async keyword

JH: is that adequate? async means asynchrony, await does not mean asynchrony, just pause the execution.

YK: Come back to this?

Agreed. Next turn of the event loop.

JHD: Agree that await x always means await Promise.resolve(x)?

Some agreement.

YK: Doesn't fully describe the trade off

MM: Implementation prohibited from making optimization

JH: can we put together a program that illustrates the hazard?

// BT:
foo().then( function() {
   /* 1 */
});
/* 2 */
// Which is first

async funcion foo() {
  /* 1 */
  await x;
  /* 2 */

  // are these the same turn?
}
foo();
// HAZARD: setup state required by /* 2 */

YK:

let x;
foo().then( function(val) { x = val; /* 1 */ } );
// what is x?

JH: Is that an issue in asap? or were there other issues?

// BT & YK:
async function foo() {
  // relies on y being `1`
  await x;
  // relies on y being `2`
}

let y = 1;
foo();
y = 2;

MM/DD/YK: discussing the hazards above.

AK: Different conditions, different behavior.

Discussion about race conditions in JS

DH: largely around the interleaving asynchronous events

  • Mark wants this to be limited

MM: confirms

YK: When type await, I expect unpredictability

MM: unpredictable interleaving of job

DD:

function dStuff() {
  if (window.state === 1) { doA(); }
  else { doB(); }
}

async function foo() {
  doStuff(); await x; doStuff();
}

window.state = 1;
foo();
window.state = 2;

MM: impossible to reason about a program without knowing something about what is going on.

  • testing in sync case, and it works
  • execute in async case, and it fails

DD: Always have a consistent state on the next turn

Discussion, restating positions back and forth.

  • Promise cancellation:
    • Depends on cancellation at the promise level
    • Urge promise champions to consider ergonomics with async functions

BT: not going to specify cancellation in this proposal

MM: Not sure that base Promise is going to change?

DD: Talk offline.

  • Await at top-level
    • Can you await at the top level of a module?
    • Useful, especially in Node

DH: Issues.

YK: Previously, could assume that top level ran start to finish, if many pieces have setup await

AWB: this changes the entire model of module execution

BT: modules are wrapped in async function which called immediately

MM: after top level await point, import/export, are these effected?

AWB: initialization happens in the order of import/export but before the module body starts

MM: only "when" the execution happens

AWB: This could be misunderstood

DH:

import ... from ...;

let m;

if (dev) {
  m = await local.import("lib-dev");
} else {
  m = await local.import("lib-production");
}

export let x = 17;

DH: Requires module be async.

Unresolvable if node remains sync at the top level.

(break)

DH: we need to do more work offline.

BT: is top level await worth pursuing?

DH: Addresses a definite need, eg. dynamic module loading

BT: Flesh it out?

DH: No, this needs to be designed in concert with loader. Suggest decoupling to unblock async/await

BT: Confirms.

  • Waldemar's grammar concern?

WH: (presenting now)

async(a=await/
  • According to cover grammar, this is a division symbol
  • Is await a keyword or identifier here?

BT: parsed like a keyword, but there is a static semantics that says any occurence of await expression is an error.

async(a=await/x, b=c/i) => b;
  • Parse cover grammar, don't know that you're in a arrow function. This lets await sneak through as an identifier
  • When you do the reparse, /x, b=c/i is treated as a regexp

MF: The reparse says it has to match this additional grammar, same set of tokens

WH: It's not clear in the spec.

BT: Yes, the await would appear as an identifier until you apply the cover grammar.

MF: (reads from ECMAScript 2015 specification, section 12.2.1.1

MF: if await is always an await expression, this would fail to reparse, resulting in a SyntaxError

BT: Correct, expected.

BT/WH to have offline discussion re: grammar.

BT: Those that know execution model should review this.

Conclusion/Resolution

  • async (a, b) => await a + await b; contingent on grammar validation
  • async functions: no construct slot
  • errors occuring in parameter initialization take the catch path
  • Approved for Stage 2
  • Reviewers
    • Waldemar Horwat
    • Jafar Husain
    • Yehuda Katz

6.5 Proposed Changes to Observable API

(Jafar Husain)

zenparsing/es-observable/tree/zenlike

Slides

JH:

Conclusions after 45 Issues and Impl Work

  • Generator should not be used Sink
  • Sync Subscription Affirmed Necessary
  • Can implement EventTarget using Observable

Using Generators as Sinks

Issues:

  • Type Fudging (would like implicit {done: true})
  • Priming Problem
    • issue with implicit yield
    • considered a decorator, but likely a footgun
  • Return invoked on unsubscribe
    • mistake because it conflates two concepts: the need to free scarce resources and the need to signal iteration has completed
    • the equivalent to breaking out of a for loop,

YK: Why does it end up not being important to generators? (dispose being separated from return)

YK: Straight forward to add a dispose() method to Generator instance objects www.ecma-international.org/ecma-262/6.0/#sec-properties-of-generator-prototype

JH: Believe adding dispose() is good

DD: And/or remove return(). To remove the try/finally that's implicitly added around a for-of loop

Discussion, re: try/finally

JH: even if we fix the return/dispose conflation, the priming problem is still a compelling reason not to use generators as sinks

Using Generators as Sinks (continued)

Issues: ...

  • Multiple unsub methods

Proposed Solution: Observer Type

(get bullets from slide)

Advantages of Observer Type

(get bullets from slide)

Proposed Observable Type Changes

(get code from slide)

DD: Strange to hide a method by using well-known symbol

  • if sync subscription is allowed, just make it easy

WH: What does Symbol.observer return? (Not referring to the symbol, but to the method to which this is the well-known symbol-as-computed property name)

JH: Nothing

DD: What happened to the flush that we discussed?

JH: In progress

MM: What is the Object? in Observer type?

JH: Allowed to return something

(Should be "any")

MM: Why not just support the Observer (in subscribe method)

  • Prefer two separate methods

JH: previously had a forEach that returns a promise, still exists, just not shown

Discussing a swath of code on jsbin

Sync Subscription Affirmed Necessary

  • Necessary to build EventTarget using Observable (get rest of bullets from slide)

Jafar moves through slides too fast.

DD: Would prefer something simpler than Symbol.observer, instead just call it something obvious

MM: Name it such a way that the name is clear to the user (no suggestion)

Discussion, re: await observable.

All scalar combinators produce promises or observables

Conclusion/Resolution

  • Approved for Stage 1 (which means: nothing changed here)
  • Offline discussion, re: sync subscription

6.13 Advance Rest/Spread Properties to Stage 2

(Sebastian Markbage)

sebmarkbage/ecmascript-rest-spread

SM:

Static Properties vs. Computed Properties

SM (slide): question on evaluating computed property keys multiple times on the LHS of a destructuring assignment?

SM (slide): question when a "rest" destructured object param throws (via getter, for example), should rest be undefined, or a partial object. or, should the getter be copied rather than evaluated

try {
  var throwingObj = {
    x: 1,
    y: 2,
    get z() { throw myError; },
    w: 4
  };

  var {x, ...rest} = throwingObj;

} catch (err) {
  x; // 1
  rest; // undefined (could be { y:2, w: 4 })
}

MM: possibilities?

SM:

  • undefined
  • { y: 2, w: 4 }

MF: also {} and { y: 2 }

MM: further semantics need to be explored

Conclusion/Resolution

  • Approved for Stage 2
  • Reviewers
    • Andreas Rossberg
# Andy Wingo (9 years ago)

On Wed 05 Aug 2015 17:19, Rick Waldron <waldron.rick at gmail.com> writes:

6.7 new & GeneratorFunction

(Brian Terlson)

Slides

BT:

Current Semantics:

  • [[call]] this set normally by caller
  • [[construct]] this is a dynamic ReferenceError Issues:
  • Potentially confusing
  • new doesn't do anything useful Possible Solution:
  • GenerationFunction doesn't implement constructor, so new throws
  • this is not a dynamic ReferenceError, but instead refers to the GeneratorFunction instance (align with current implementations: Babel, V8, SM)

FWIW the behavior as implemented in V8 aligned at one point with a spec draft:

ecmascript#1489

Andy

# Herby Vojčík (9 years ago)

Rick Waldron wrote:

(Slides are at tc39/tc39-notes/tree/master/es7/2015-07 )

July 30 2015 Meeting Notes

Allen Wirfs-Brock (AWB), Sebastian Markbage (SM), Jafar Husain (JH), Eric Farriauolo (EF), Caridy Patino (CP), Waldemar Horwat (WH), Istvan Sebastian (IS), Mark Miller (MM), Adam Klein (AK), Michael Ficarra (MF), Peter Jensen (PJ), Domenic Denicola (DD), Jordan Harband (JHD), Jonathan Turner (JT), Paul Leathers (PL), Chip Morningstar (CM), Vladimir Matveev (VM), Ron Buckton (MS), Brian Terlson (BT), Alan Schmitt (AS), Ben Newman (BN), Mohamed Hegazy (MH), Abhijith Chatra (AC), Tom Care (TC), John Neumann (JN), Dave Herman (DH), Brendan Eich (BE), Daniel Ehrenberg (DE), Dan Gohman (DG), Andreas Rossberg (ARB), Rick Waldron (RW), Mike Pennisi (MP), Akrosh Gandhi (AG), Jonathan Sampson (JS)

6.4 Advance Async Functions to Stage 2

(Brian Terlson)

Slides

BT: Updates from Last Time

DH: Future proof for potential future syntax extensions

DD: Clarify not await *

BT: await * was not useful. If there is a proposal for a useful semantics, then good, but not in this proposal.

Questions

  • Async Arrow Function
    • async (a, b) => await a + await b;
    • (a, b) @=> await a + await b;

DE: What's the issue with the first?

BT: async not a keyword and that could be a call: async(a, b)

MM: @ seems like a poor choice, but I don't have an alternate suggestion

Just a feeling-based one, but contrary to the straight sync =>, the

async could be curly ~>.

# Rick Waldron (8 years ago)

July 26 2016 Meeting Notes

Brian Terlson (BT), Michael Ficarra (MF), Jordan Harband (JHD), Waldemar Horwat (WH), Tim Disney (TD), Michael Saboff (MS), Eric Faust (FST), Chip Morningstar (CM), Daniel Ehrenberg (DE), Leo Balter (LB), Yehuda Katz (YK), Jafar Husain (JH), István Sebestyén (IS), John Neumann (JN), Domenic Denicola (DD), Rick Waldron (RW), Stefan Penner (SP), Jonathan Sampson (JS), Caridy Patiño (CP), Sam Tobin-Hochstadt (STH), John Buchanan (JB), Kevin Gibbons (KG), Lars Hansen (LHN), Peter Jensen (PJ), Tom Care (TC), Dave Herman (DH), Bradley Farias (BF), Kris Gray (KSG), Adam Klein (AK), Dean Tribble (DT), Eric Faust (EFT), Jeff Morrison (JM), Sebastian Markbåge (SM), Saam Barati (SB), Kris Gray (KGY), John-David Dalton (JDD), Ben Newman (BN)

(I need the list when it's complete)

Template link: tc39/Reflector#19

Introduction

JN: (agenda)

IS: (wishes to determine a log.... I am not sure I understand what this means... :-))

DE: We could go through the agenda and appoint reviewers for each topic

DD: I think we should appoint note-takers at the beginning of this meeting

YK: I think we should appoint note-takers as we start each topic

RW: If we have different note-takers, they might not follow the right format, making my job of cleaning up the notes harder

DE: Let's defer to Brian when he gets back

IS: Different Ecma groups do different things; there is no single solution. Some e.g. only record the subject and outcome of the discussion, but not the actual discussion itself. This has to be decided by the TC. Anyway, with the current practice, which is very similar what the W3C does, we need the support of the group. e.g. Ecma can not hire any pay for a professional technical notetaker, that has to be organized / fulfilled by TC39 members.

JN: Looks like some things are timeboxed

BT: Does anyone want to volunteer to take notes the whole day?

RW: Me

AWB: (punt on addressing this now?)

BT: Let's go with Rick taking notes for now, since he volunteered, but long-term we'll go item by item

Conclusion/Resolution

  • Moving on, further discussion to be on github as before this meeting. Interested members are encouraged to participate there directly.

3 Agenda Adoption

  • Approved

4 May Minutes Approval

-Approved

JN: Agenda?

(Discussion re: backing documents not present for a handful of agenda items, should we start requiring these?)

WH: I'm fine with occasional items not having backing materials — there are situations where that's appropriate — as long as they're relatively rare and not looking to advance.

WH: ECMA has a global policy (we all agreed to) that documents up for significant decisions shall be provided 2-3 weeks in advance. I'd interpret this as applying to proposals looking to advance in TC39.

IS: It's 3 weeks. This is e.g. to formally move forward or approve a TC39 draft speciafication. But for things for information, to start a discussion on new items, not to strive for a formal decision anything until the meeting is allowed. But of course it is encouraged to submit and post on Github as soon as possible.

JN: Approval of minutes?

Conclusion/Resolution

  • Agenda Adopted
  • May Minutes approved
  • Add item to discuss the agenda item locking.

5. Report from the Ecma Secretariat

IS: Submitted the ECMAScript Suite Standard (approved by the GA as Ecma 414) to ISO/IEC JTC1 for fast-track. This should enable not to submit anymore ECMA-262 and ECMA-402, etc. to JTC1 separately anymore. This would allow to solve the speed difference problem and the RF patent policy problem. However, JTC1 editors wanted to have more text in the standard and not only the list of normative and informative references. IS said that he will work with Allen Wirfs-Brock on that. If possible we try to beed up ECMA-414 until the September 2016 meeting that isót can be approved as new Edition in the Decemmber 2016 GA. If the plan is delayed we finish it by June 2017.

  • Link IETF spec to Ecma 404 (that was already fast tracked to ISO actually before the May 2016 TC39 meeting). On that one JTC1 has not given any feedback yet. So we guess that is on track.

  • On the issue we are in close contacts with the IETF. When we get the IETF spec number (when available) we will make a 2nd Edition of ECMA-404 and fast track that edition to JTC1. With that we want to link the Ecma Standrad with the IETF specification that they should be in full harmony.

  • Awards: BT and RW received ECMA awards for ECMA-262 7 th Edition and ECMA-402 (plus the many notetaking). Congratulations!

  • New Executive Committee, made from a combination of ECMA management and the former Coordinating Committee.

    • A change from the past is that up to two ECMA members from categories other than ordinary members may now be elected into the the Executive Committee. Nominations for that can come from anybody, but in the end the December GA will vote on the nominations. The membership in the Executive comiittee is always one year, but with the possibility of reelection.
    • All members can now participate in the General Assembly and take actively part in the discussions, not just ordinary members. However, only ordinary members can vote (that is unchanged).

    -IS also noted that TC39 is now by far the largest Ecma Group and it has grown to a size where he feels that we have to organize our structure and work better, otherwise at the face-to-face meetings there might be disappointment by some who prepare for a topic for discussion and presentation but in the shortness of time the subject is not discussed properly. Discussion on that to be continued by those who are interested on GitHub.

    • What IS forgot to tell, that actually with the publication of ECMAScript 2016 and ECMA-402 new Edition etc. it would be a good idea to make more PR, e.g. Press Release.

8. Test 262 Status Update

IS: Technical Report 104 needs to be updated. He added that all specs related to TC39 work are being downloaded very heavily (actually at least 2/3 of all Ecma downloads are TC39 related). The HTML version of ECMA-262 and ECMA-402 is in addition to it, and compared to full downloads that is even significantly higher.This is actually more than e.g. what is being downloaded from the ISO Shop (of course that is not free of charge...). So automativally also TR-104 gets downloaded rather heavily. But e.g. in TR/104 the URL to the tests does not work. Also the text needs to be updated. It reflects a situation when only ES5 was covered, but e.g. not ECMA-402.

AWB: Propose updating TR 104 to be descriptive only?

BT: Is this just a readme? Possible get rid of it?

AWB: Just reduce to an abstract description of the content and motivation of test262

DE: Should ecma site link to draft spec?

AWB: The draft isn't the published standard

(Suggestions to link both, with clear identifiers)

Note IS: I did not say that in the meeting, but In case of TC39 actually we give links to the latest ECMAScript drafts.

Conclusion/Resolution

  • Bring to reflector for further discussion
  • TR104 update (or withdrawal)
  • Linking standard and draft?
  • It's there, but some want it to be more prominent

Note IS: The TC39 website pages at Ecma have always room for improvement. If anything you want to include just contact Patrick from the Secretariat who maintains the webpages.

6. Ecma 262 Status Update

Brian Terlson

BT: 6 months left for ES2017

  • Object.values
  • Object.entries
  • String.prototype.padStart
  • String.prototype.padEnd
  • RegExp changes to case insensitive flags ( tc39/ecma262#525)

AWB: (questions about consolidated changelog that provides complete document of changes from previous edition to present edition)

YK: Make a single place for all published changlogs?

BT: There has never been such a document, isn't Annex B's change listing sufficient?

  • Want changelogs in annex?

AWB: Yes

DD: Use links instead of copy/paste?

BT: Links to releases tab?

AWB: Cannot stand alone without github

BT: (has a plan)

...

AWB: Do we have a "focus on 2017 items list"?

BT: No, not yet.

JHD: Benefit of knowing what year a thing will be ready?

BT: Addressing the cross cutting issues, knowing the big picture

AWB: Resolving issues discovered in an implementation

BT: Champions responsible

Conclusion/Resolution

  • Bring to reflector for further discussion
  • Need changelog for each edition
  • Discuss form/forum/format

7. Ecma 402 Status Update

Caridy Patiño

No updates

8. Test262 Update Revisit

Leo Balter

LB: Bocoup has just wrapped project delivering coverage for ES2015

  • Iterating on feedback from other members
  • Moving forward on ES2016 tests
  • More work to be done, but need volunteers
  • Deprecated Python runner
  • Working on test262 harness that runs from node.js

DE: Work to be done on test262 presence

  • Spoke with Kangax about including test262 in the compat table sites

LB: More visibility for test262

TC: Need help with reviewing contributions

  • Promises
  • Yield

TC: Barrier to entry quite lower based on the work that's been done in the last year.

SP: (asking about test submission with new features)

BT: Staged features require tests. Known issue: normative changes haven't been blocked by any requirement for tests

RW: Previously, not a lot of contribution, so this wasn't an issue. Now we're seeing more contribution, so it needs to be addressed (this is a concern that we have at Bocoup)

BT: Possibly a requirement to create an issue on test262?

SP: Block merge?

Conclusion/Resolution

  • Labels to mark normative changes that need tests
  • Work with change author to make tests
  • Block on normative changes until they have tests
  • Due diligence on both the tests and normative spec changes
  • Authors, champions, leads must be satisfied with changes on both repositories
  • Include mention of available mentorship for test writing.

9.i.a Reintroduce for-in-initializer

Kevin Gibbons

Slides: docs.google.com/presentation/d/19LVVdCHfokJWQnNvkyu8M2vdpMAz8yIE1wB8yK7hLB4/edit#slide=id.gc6f980f91_0_0Slides :

KG: V8, SM, JSC implemented and later reverted. Chakra did not implement

  • Web breakage happens!

Proposing changes to Annex B

AWB: Annex B are generally items not allowed in strict mode

KG: Not consistent

YK: Can we make illegal in strict mode?

KG: Chrome does

?: JSC does too

AWB, WH: So we should add for-var-in initializers with the old semantics to Annex B, for non-strict mode only.

RW: (brief discussion about strict mode additions: resolved, non-issue)

YK: Does this mean sloppy mode changes are always in annex b?

Generally, no.

Conclusion/Resolution

  • Add for-var-in initializers with the old semantics to Annex B, for non-strict mode only.
  • ecma262/pull/614
  • Kevin will write tests for the change, based on the new policy

9.i.b Update on Async Iteration

Domenic Denicola

(No slides)

DD: Kevin Smith has left the committee; I am taking over as champion. I did not have time to address spec issues, so it is not ready to advance, but they are minor and I will work on it. Who should be Stage 3 reviewers?

Conclusion/Resolution

  • Reviewers: Bradley Farias, Daniel Ehrenberg

AWB: Going back to the previous topic, Kevin, could you please share a PDF on the notes page, since links rot?

9.i.e Trailing commas in functions

Jeff Morrison

JM: It's implemented in two browsers (JSC, Edge)

AK: Actually V8 also

BT: Actually we ship it already. Are there test262 tests?

JM: I thought so. Stage 4?

WH: I don't object to advancing this to stage 4, but I'm sad to see this in the language.

?: Ditto.

(We can't find tests)

Conclusion/Resolution

  • Stage 4 pending on writing and merging test262 tests

9.i.f Unify String and Array maximum lengths

Michael Saboff

MS: Unify the length of strings and arrays. Strings are 2^53-1, Arrays are 2^32-1 indexed elements. A few APIs cross over. Really, browsers are all 2^31 or less. I don't care which way we go, but I'd like Strings and Arrays to be unified. Maybe we should delay this a little until we figure out how to make Arrays bigger; I originally proposed reducing everything to 2^32-1

MF: What's the motivation?

MS: Consistency, so they all use the same type of index.

AWB: There was a lot of thought that went into it. We increased the size of everything that we could — strings, typed arrays — and held off on Arrays for compatibility reasons.

DD: As Michael was saying, in current VMs this isn't a good idea, but maybe in a few years, it could be reasonable.

AWB: And Arrays can be sparse anyway

YK: Seems like a bad idea. Use Maps here instead for spare Arrays, or TypedArrays for big Strings or Arrays. We have TextDecoder in the DOM to deal with TypedArrays that have encoded Strings.

DD: Why not even lower?

AWB: We use 2^53 for basically everything, except for Array length calculation, which maxes out at 2^32-1

DD: It seems like bigger would be better

DE: What was the web compatibility evidence presented in the past?

BE: The motivation [of increasing it] was weak, and no one wanted to jump on the hand grenade.

AWB: Well, we have a motivated implementer here. Maybe Michael should try it out.

MS: I don't think any browser believes we need more than 2^32 for browsers. However, for servers, it could be an important limit to hit. I don't think this is important for JSC as we are just a browser implementation.

AWB: There's a chicken and egg problem. Someone has to prove the feasibility of it, and you're the only major implementation who has brought it up as a possibility.

MS: My proposal was to make string lengths smaller.

AWB: We don't want to make string lengths smaller

DD: It would be nice if everything were as big as it could possibly be, but I don't have a problem with making it smaller

AWB: The max size is implementation-dependent

YK: It seems OK to just choose the lowest common denominator size

BF: It seems like large Arrays or Strings are important for some applications

YK: We can just make those things use TypedArrays. Wouldn't you want to use binary data for such big things?

WH: We'd need to shrink TypedArrays too if we're shrinking strings; otherwise we wouldn't get the consistency that's the whole motivation of this.

EF: If we don't shrink TypedArrays, we wouldn't get a level paying field.

AK: What is the motivation for this change, given that JSC already limits strings to 2^31?

MS: It's consistency. In regular expressions, for split, we have to do these 53-bit calculations, but really strings are smaller

AWB: For split, we made a change to use ToUint32 rather than ToLength, but we should've made it throw

AK: that's a separate proposal

AWB: It's gotten worse with recent changes

DE: We've hit the timebox limit; Add this to the end of the agenda?

MS: This isn't a hill for me to die on; i think it's something we should address, but not my #1 priority

Conclusion/Resolution

  • Not finished; will revisit

9.i.h Standardize Date.UTC when called with < 2 arguments

Brian Terlson

BT: All implementations except Edge return NaN for Date.UTC for < 2 arguments, but Edge treats those missing arguments as 0.

AWB: What discussion have we had before?

BT: I couldn't find it. As Chakra is the only holdout, and we have no compelling reason, we're willing to return NaN. So I believe we should update the spec text and return NaN, and Chakra will do that.

DT: Is this part of a more general principle?

DD: Actually the spec had a specific cop-out there

BT: OK, consensus on the change?

AK: Are there test262 tests?

BT: I'll write them! But I'll merge the Chakra PR first

AWB: Why not actually make them optional like Chakra does? Maybe those are good semantics.

YK: We're just standardizing what's there in browsers

DD: Does anyone want to experiment?

BT: We're shipping this already. I'm concerned about interoperability.

YK: NaN is horrible and we should avoid letting it leak out into programs.

DE: We can't generally be in the business of making bad arguments to things return useful values. Date uses NaN all over the place as a way to stand in for something having gone wrong. The Date library is horrible and legacy; our job should be to standardize what's there. The Date.parse presentation will show a significantly worse case than this, but we should standardize it anyway. Given that we have three browsers agreeing, we should just standardize that. I would be OK with standardizing the other behavior.

WH: We shouldn't create a second Date library just to fix this, we should make this one good.

WH: UTC(year) should return the first day of that year, just like UTC(year, month) returns the first day of that month. We know that works because Chakra does it.

AWB: Oh, I see what's going on. This fills in a missing case from the Date overload. Date does something completely different when passed one argument than when it gets two.

BT: Let's pick one of the two existing semantics, not something in between. Oh, wait, it's actually December 31, 1899

DD: that's two-digit year 0, timezone-shifted

DE: Sounds like Chakra's semantics are significantly bad

BT: Let's standardize returning NaN now, and we could revisit it later.

DE: Returning NaN is sorta like throwing an exception, so we could make it return a useful value later. DE: We are running into the timebox. Do we have consensus on the PR?

WH: No. I think that, barring additional evidence, it would be good for the one-argument case to return the beginning of the year. I'm fine with NaN for the zero-argument case.

AK: What would be the use case for this? is it worth it to ask implementations to make this change? We're making a normative change; there should be some reasonable motivation.

BT: It's a grand compromise

AWB: 1) Interoperability among implementations 2) Usability going forward--what would users expect? This is forward-looking, not backwards-looking.

BT: That seems like a reasonable rational. Are other implementers reluctant to return a useful value for that case?

AK: My point is a little higher-level, that if we are making normative changes, we should have a motivation for it.

AWB: Good design aesthetics would be to revisit what things are, rather than just polling implementations

AK: This is adding to the incompatibility for the future and churn.

BE: It is what it was. I support the status quo, copying Java, returning NaN

MS: I support returning NaN for less than two arguments, just because of the confusion that Date has 0 arguments, 1 arguments, and then 2 or more is just like Date.UTC

AWB: The Date constructor has an overload for one argument, so it can't treat that as the year and be analogous to Date.UTC for the one-argument case.

Conclusion/Resolution

  • No consensus on the full change. The zero-argument change is agreed to return NaN, but disagreement about what the one-argument case

9.i.d Revisiting NaN

Daniel Ehrenberg

tc39/ecma262#635

Slides: docs.google.com/presentation/d/1eqimbmVpMZET_5H9NacVkXGP2WNATg8bXWi3Ky2bsGo/edit

DE: (presenting slides)

  • Some implementations fit pointers in NaN payloads, so canonicalize
  • V8 does not do NaN tagging, so pointers are 32-bits on 32-bit archs
  • Extra canonicalization writing into a TypedArray is a perf regression (see slide for link)

Slide: "What does ES2015 day about NaN?"

  • The Number Type "to ECMAScript code, all NaN values are indistinguishable from each other"

  • SetValueInBuffer( arrayBuffer, byteIndex, type, value [ , isLittleEndian ] ) "An implementation must always choose the same encoding for each implementation distinguishable NaN value."

DE: ok with: "anytime you use SetValueInBuffer, use whatever you have"

"Why would property writes make a new NaN?"

SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ , isLittleEndian ] )

  • V8's FAST_HOLEY_DOUBLE_ARRAY ElementsKind
  • Sample code:
let x = new Array(6)
for (let i = 0; i < x.length; i++) x[i] = 0.5
  • Initially "filled with holes" (missing properties), then entries are added V8 canonicalizes NaNs when setting elements into such an array so it can have a distinct "hole" NaN value

WH: This is an instance of the general problem that implementations will sometimes do NaN-boxing and sometimes not within the same program, depending on code and data structure optimizations.

DH: Easiest solution: maximally non-deterministic: allowed to non-deterministically change bit pattern Problem: many places possible to predict the bit pattern. Can convey information, want to preserve that preciseness.

MM: Uncontrolled non-determinism of NaN bit pattern, depends on unspecified nullable

(discussion re: intentionally evil implementations)

WH: My view is that what NaN bit pattern you get should be unspecified. I understand MM's concern and wouldn't want them to be evilly unspecified, although I'm not sure if there is a reasonable way of expressing that.

  • timebox ran out, discussion continued *

DH: expectations:

  • want implementation flexibility, use cases for changing bit patterns
  • frozen properties, should not be able to reliably observe changes

DH:

  • NaNs carry around bit pattern,
  • specific places can scramble
  • specific places preserve

EFT: Over the time box, no new points made

MM: Don't understand the optimization in V8

AK: I think this needs to be discuss offline?

DH: (taking issue with time box)

DH: Some predictable behavior that has changed over the years and some implementations are doing different things, new use cases.

Conclusion/Resolution

  • Allen, Mark, Dave, Waldemar, Dan to have discussion and come back for another time box discussion.

(More discussion re: time box)

9.ii.a Object.getOwnPropertyDescriptors: when a Proxy returns an

undefined descriptor?

Jordan Harband

JHD: Any non-proxy, call built-in op claims foo in object, call Object.getOwnPropertyDescriptor(foo, "prop"), you get that property descriptor. Proxy can lie, which is problematic when passing the returned value from Object.getOwnPropertyDescriptors(...)

BT: Side-effecting proxies. If a proxy says "no descriptor for this property", then there is none. Object.getOwnPropertyDescriptors(...) shouldn't be seen as the authority.

  • Property should be skipped on the grounds that "it doesn't exist"

MM: once an obj is not observable, ownkeys cannot give an answer that was not previously true

DE: Cait Potter implemented both semantics and there are no noticeable differences.

AWB: No guarantee once you get a descriptor that it remains valid to do something with it in the future - operations are unknown

JHD: The change is: only properties with valid property descriptors are returned.

Conclusion/Resolution

  • Recommended change approved for merging the PR

AWB: obligated to notify implementors?

JHD: Implementors are aware and following progress

9.ii.b Object.enumerable{Keys,Values,Entries}

Leo Balter & John-David Dalton

LB: Discussing leobalter/object-enumerables

JDD: No built-in API that allows getting own and inherited properties

EFT/DD: for loop?

JDD: Want built-in functionality, not syntax

DH: Something more?

JDD: Allows a shim path.

DH: An example?

JDD: (showing an example in lodash)

STH: Can't the shim write the for in loop?

DD: Spec seems to treat objects as maps, but specifically objects and their prototype properties as values in the map

JDD: (further examples, showing: leobalter/object-enumerables#use-cases )

DH: Not impossible to write in library code?

JDD: no, but not the point

STH: Offers shim authors something to coordinate on to fix bugs in older browsers, but not sure we should be in the business of doing so.

YK: It's rare to encounter an enumerable property on the prototype, it happens

  • If there are properties on a class prototype that are enumerable

AWB: Effectively creating for-in

YK: Yes

DD: Do we want to further encourage the programming model that these encourage?

MM: (concurring, discussing value of such a feature)

DH: A number of libraries want to use this functionality and it would be nice expose as built-in, but why not define in one library and that's that.

AWB: Back to "inherited, enumerable things". The only definition we have is via for-in

DH: can also crawl the prototype chain

AWB: then have to impose your own rules re: side effects

BE: for-in is bad legacy

"Never invest in the trailing edge"

DD: Adding new features, in new browsers, to fix features in old browsers, is not what we should be doing.

MM: I don't think this is going to get consensus

Conclusion/Resolution

  • No advance

9.ii.c RegExp Unicode Property Escapes

Brian Terlson, Daniel Ehrenberg, Mathias Bynens

mathiasbynens/es-regex-unicode-property-escapes

Slides: docs.google.com/presentation/d/1o31S9RqDdkoWW2zfPMNIZdPDIp25Rr0-XW0gro_cskk/edit

DE: Expose more unicode data to RegExps

  • Properties with values: /\p{UnicodePropertyName=UnicodePropertyValue}/
  • Binary properties: /\p{LoneUnicodePropertyNameOrValue}/ Inverse:
  • \P

Example:

i.gyazo.com/0dcfc195d891a36c4b0c04d460cb5d72.png In text form: mathiasbynens/es-regexp-unicode-property-escapes#illustrative-examples

DE: Have full spec text, implementation in V8, tests for V8 (need to be updated for test262)

BT: If ok with deviating from what’s allowed inside \u, then we can overload \u instead of \p

(TODO: @rick we'll likely have to escape those ^^^^^ when this is published as markdown)

DD: Are there conflicts with other languages and use of \u?

WH: \u could be trouble if anyone comes up with classname consisting entirely of characters A-F

DE: I can find out if this is an invariant that will be maintained. If it is, then we should use \u, otherwise \p. If Unicode advises us not to depend on existing \u invariants, then we won't

DE: Stage 2?

MF: Is there a syntax error when type any random character where in /\p{UnicodePropertyName=UnicodePropertyValue}/, /\p{LoneUnicodePropertyNameOrValue}/ ?

DE: No UnicodePropertyName syntactic restrictions in present spec

Addendum by Mathias: a SyntaxError is thrown at runtime in such cases. But yeah, maybe these should trigger early errors instead? No strong opinion here.

AWB: Need to specify the syntax

WH: If we choose to use \u{}, then we must make unknown classes (or typos) into early errors because we need typos in hex numbers to be early errors. With \p{} we'd have a choice of standardizing on early or runtime errors.

Revisiting String.prototype.normalize specification.

This may need to be "normative optional"? Inclusion of new data tables may be problematic?

Discussion re: ICU data, Unicode data on constrained devices.

RW: When Tessel 2 moves to Node 6, we'll be shipping Node.js compiled with the disable flags, which means normalize is useless, but the additional data isn't included.

AWB: Can define it such that, if the data is not available, the character set is empty

DE: Stage 1?

Conclusion/Resolution

  • Stage 1: Approved.
  • YK wants confirmation about \u

9.ii.d Async Functions for Stage 4

Brian Terlson

BT: no updates, no changes

  • Shipping in Edge
  • Implementations in V8 and SpiderMonkey

YK: Worried about cancellation?

DD: Cancel token integrate well with async functions

YK: Not at stage 2 with cancellation, hard to be sure that it's compatible

KG: not sure it could change, given widepsread use in transpilation

YK: (concerns with cancellation intuition)

DE: the correct time for this was prior to stage 3

YK: I made these objections then

DE: I'm pretty optimistic about Domenic's cancellation specification

DD: If I had held off on Cancel tokens, this would've made it to stage 4

BT: Off topic.

YK: Certain assumption that one can reasonably assume that an expression that exist can become abrupt

  • Have to know that X cannot throw
  • Cancellation exists, now X might throw

WH: I'm trying to understand the concerns here. Should this proposal be blocked on the cancellation proposal advancing a few levels?

WH: I hear vague uneasiness about interactions between async functions and cancellations, but need something more concrete to be able to judge the merits.

BT: willing to postpone this until we know more about interaction with cancellation

SP: Can we revisit this after cancellation?

(Discussion, re: some people that object, that are apparently in the room, but aren't speaking)

MM: concerns: === should never throw, typeof should never throw. I don't recall where cancellation would make await throw, where it previously would not throw.

Was

DD:

async function foo() {
    try {
        await f();
        g();
    } catch (e) {
        h();
    }
}

might call neither g nor h. But then there are other situations where neither g nor h is called. Use finally if you want cleanup code.

DD: Objecting to the third

JHD: If f is changed to return new Promise(() => {}), then both g and h will never run now, without cancellation existing - therefore if you expect g or h to always run, you are simply wrong, and your expectation is invalid.

async function foo() {
    try {
        await f();
        g();
    } catch (e) {
        h();
    }
    i();
}

DD: however, currently you can guarantee that either g or h will always run before i, and it's possible with cancellation that this might not hold.

MM: the example here has nothing to do with something that was not abrupt, becoming abrupt

  • A new way to be abrupt, in addition to the old way to be abrupt

DH: If from scratch, no issue. The issue is that catch expectations no longer valid.

DD: There is past precedent for moving ahead. We introduced proxies, which created objects that behaved outside the past invariants that code might have relied on. We introduced new typeof types with similar effect.

JHD/EFT: No call site can be defensive against code it didn't write

JHD: In the case of Promises, if you're returning a promise that you didn't create, in a then, you can't defend against it, because you can't know if the other promise will ever settle.

(Questions about "Third State")

Conclusion/Resolution

Will revisit after discussing cancels more; hopefully reshuffle non-timeboxed agenda items to enable that to happen in this meeting.

9.ii.e Math extensions

Rick Waldron

RW: There are some nasty npm modules for these sorts of math functions. This comes up in IoT, cool animations, etc. We could add some more functions to the standard library. This stuff happens over and over and over again; typing things into consoles.

YK: leftPad went well

RW: This falls into the leftPad box. This is putting down pavement where a cowpath once was.

RW: Math.constrain: Could be called Math.clamp. Like Uint8ClampedArray. Very straightforward.

RW: Math.map is just scaling x from one range to another

YK: scale is better than map

RW: Scale is my favorite actually; I didn't want to seem biased. fmap is the version where the result is converted to a float32.

DD: Looks like it'll move x to the corresponding point in the 'out' linear range as it was in the 'in' range.

RW: Yes

DD: Why not just use fround composed with it? Is there a hardware operation for this?

RW: No; we can take this or leave it

AWB: Since we're doing multiplies, the fround won't end up commuting with the operations, so this won't get those efficiency advantages. This is specified to do double precision scaling. This is just a nice-to-have.

DH: is every one on the list something that you found in other languages?

RW: Yes, the readme has links to standard library features analogous to these in tons of other languages.

MM: Shouldn't these be in a new built-in module?

RW: I'd love to do that. If between now and 2017 lockout day, I will change the writing for that.

DH: Part of your motivation is that it's trivially accessible from the console, and you can't import from the console.

RW: If it's a built-in standard lib module

DH: From the console, that extra line is a pain, and further, I can't see why we should be inconsistent with the other Math functions that exist. Seems silly to be out of sync with each other.

DT: Built-in modules just in the console?

MM: Seems like adding functions for radians and degrees when they are so trivial is just a waste of time.

DD: I don't feel so strongly about this, but taking conversions for different unit systems takes Math in a totally different direction.

RW: If you look at other languages, they include these conversions for radians/degrees and not other things

STH: And degrees are unitless

DD: They are not natural

CM: But degrees are widespread as a notation

DH: There's a high bar for adding something to the JavaScript standard library, given that our library is rather more limited. We do want to add things that are common enough.

RW: And it's painful to install someone's bad npm library

DH: We make these generic arguments about the benefits of standardizing functions, but we can't standardize all functions in npm. The argument should be, we know what the costs are, we know that we can't do it for everything, so we have to make the argument that these are extraordinarily common for important use cases.

STH: Two other reasons why these functions have a strong claim: Unlike other domains, JavaScript has as reasonably strong Math standard library, for historical reasons, and so programmers expect Math.whatever to be the math standard library in a way that they don't expect for Strings or TCP connections. Second, these are things that are commonly in the standard library of other languages. Yet again, programmers expect, when they look for functions like the ones Rick is proposing, where their counterparts are in other languages.

DD: I agree with these points, but maybe we should group these under "Units" and include time constants, also RAD PER_DEG not "TO"

YK: I agree that time conversions are very common.

RW: I'm asking for stage 1.

JHD: Do we expect to devote time to the problem space?

RW: Single-precision values are important because some datasheets ask for things to a certain precision. You want the rounding to happen in your own code, not implicitly when writing it into the actual register. But really, Math.fmap is not all that important.

WH: I was wondering why we have fmap but not fmax, etc. What does this actually do?

RW: It maps a range

YK: We are interested in this subject; in stage 1 we can look into unit conversions generally

DD: I feel really strongly that it shouldn't be in Math

JHD: We don't have to come to all of these answers in order to get to Stage 1.

RW: As part of Stage 1, I will document why these should go within Math

MF: I want to define a selection criteria for math functions. This seems like a random bag.

RW: I used subjective criteria, for what is the most painful in my everyday programming

DH: Some possible selection criteria: 1) Incredibly high applicability 2) known hardware fastpaths

DE: Or known VM fastpaths, like Object.values

DH: Neither of those has anything to do with whether it's in Math. Domenic makes a good point that some of these don't belong in Math.

WH: I would have expected math library extensions to include common math functions like the gamma function. Why aren't those in here?

RW: That was my long list, but I pared it down. Maybe we should be incuding a lot of functions from other standard libraries.

AWB: We went through a similar process in ES2015 where we made a big spreadsheet of various languages and functions, and chose what to add to Math based on that

RW: How about looking at Racket and Python

MF: We should look at rather broad datasources, like utility libraries for JS today, a number of different programming languages, etc

DH: We should avoid the slippery slope that, if we do one thing, we do all the things. We should have a high bar

DD: We shouldn't tell the champion that they need to add more than they want; they should be able to put in what they value

AWB: Seems like this request is a valid input.

RW: This is really robotics-driven

WH: Last time, we got bogged down in specifying precision of math functions. How should we avoid that here?

CM: If there are subtleties in the implementation, that's a good reason for standards.

Conclusion/Resolution

  • Stage 1
# Rick Waldron (8 years ago)

July 27 2016 Meeting Notes

Brian Terlson (BT), Michael Ficarra (MF), Jordan Harband (JHD), Waldemar Horwat (WH), Tim Disney (TD), Michael Saboff (phone) (MS), Eric Faust (FST), Chip Morningstar (CM), Daniel Ehrenberg (DE), Leo Balter (LB), Yehuda Katz (YK), Jafar Husain (JH), István Sebestyén (IS), John Neumann (JN), Domenic Denicola (DD), Rick Waldron (RW), Stefan Penner (SP), Jonathan Sampson (JS), Caridy Patiño (CP), Sam Tobin-Hochstadt (STH), John Buchanan (JB), Kevin Gibbons (KG), Lars Hansen (LHN), Peter Jensen (PJ), Tom Care (TC), Dave Herman (DH), Bradley Farias (BF), Kris Gray (KSG), Adam Klein (AK), Dean Tribble (DT), Eric Faust (EFT), Jeff Morrison (JM), Sebastian Markbage (SM), Saam Barati (SB), Kris Gray (KGY), John David Dalton (JDD), Ben Newman (BN), Morgan Phillips (phone) (MP), Shu-yu Gho (SYG), Paul Leathers (PL), Ben Smith (BS), Zibi Braniecki (ZB)

9.i.g Date.parse fallback semantics

Morgan Phillips

mrrrgn/proposal-date-time-string-format

MP: (see link) Date.parse accepts strings that are implementation specific, this is causing incompatibilities across runtimes with new and repeat bugs filed regularly.

Suggesting: specify the intersection of supported string formats, specify this as the fallback for Date.parse.

mrrrgn/proposal-date-time-string-format/blob/master/data/results.csv

DE: How much which is currently allowed to parse is banned under this proposal?

AWB: In general, implementations are allowed to add extensions to do something else rather than throwing whenever they want.

DE: If any impl. doesn't apply extensions to spec: what sort of strings that currently parse, would not parse (by only implementing this format)?

WH: (what are the data in results.csv?)

MP: Those are data generated by a fuzzer and the columns on the right are "yes" or "no" whether the string parsed

WH: The table lists which dates are accepted, but what dates do they generate? For a concrete example, line 30 is "may,may,-000000". It's accepted, but what date does that produce?

MP: This will parse as May 1, 2000. Almost all of this is crazy, hacks on hacks

(shock and awe)

SP: Web compatibility concerns?

MP: Working with V8 dev to add telemetry probes into V8 and SpiderMonkey. The web is fairly broken already—implementing an intersection as a fallback should not break the web.

SP: Is the goal to find the intersection, or a refinement on the intersection?

MP: Refinement.

WH: Are there places where different impl. accept a string but generate different dates?

MP: Possible, but haven't explored. So far have only looked for producing a NaN

SP: Should that be included?

MP/AWB: Yes

AWB: Can we replace "yes" and "no" in the table with the actual output?

MP: Yes

WH: Does the table include all "yes" rows (i.e. rows where the existing implementations all accept the string)?

MP: removed, there are millions.

EFT: Those are covered by the proposed grammar

MP: In the table there's a column for whether the proposed grammar accepts the string. It's the "parser" column.

WH: Row 4839 is accepted by three implementations but not the proposed grammar.

MF: There are 60 examples like that in the table.

MP: The grammar needs to accept more. The current grammar isn't what I want to propose in the end.

AWB: I want to reference back to ES5 and when we added ISO dates and what our thinking at that time was. What we did in ES5, we introduced the ISO date format and we did a quick look at this sort of stuff, and decided it was such an incredible mess that maybe there's no way to fix it. Part of the thinking there was, do we fix up this thing that's here, and identify which dates we take and which we don't take, or do we leave and assume that some day in the future we'll introduce a new API that is a date parser, and that we've designed from first principles of what dates we want to parse, and we don't simply include funny weird cases that exist in implementation-defined stuff simply because it's there. Because it's a new API, we wouldn't have compatibility requirements. That's still possible--we could try to find this intersection, or we could leave it alone and find the date parser implementation that we want.

YK: [Agree, but Date API is generally the sort of thing that accepts junk and is expected to do the right thing]

DE: Unfortunately, browsers don't have the luxury of doing what AWB suggests, and the demands of web compatibility mean that we have to support what other browsers support.

MP: noting reports that a company identified some large number of bugs being date based.

DE: We have found that at least 4 out of 10k page loads uses the "legacy date parser" in Chrome

Conclusion/Resolution

  • Stage 1

9.iii.a System.global

Jordan Harband

tc39/proposal-global

JHD: We reached Stage 2 previously, and the remaining open question is which name should be used. window would break lots of code, since everyone assumes 'typeof window' indictates whether you're running in a main page. The remaining options are self, global, and System.global

DD: there's also frames! (jokingly)

JHD: This is about breaking libraries like lodash, as well as breaking code which runs in Node. self has for a long time indicated that your code is used on the web, but it doesn't seem like a really big hazard; not much code for that. Also, self is used to store the receiver, though you can use arrow functions for most of those use cases these days. var self = this is a frequent idiom. Ultimately, if we pick self, Node is broken.

DD: We (TC39) make breaking changes to Node all the time. I think "breaking Node" is overstating it

JHD: This is a very common pattern, though it sometimes dispatches on window or module.exports.

DD: We already have a lot of ways to refer to the global. Do we really need another one? Further (lower priority), there is a distinction between the global proxy and the global object. Setting properties on the global scope sets it on the global object, but referring to it gets the global proxy.

(Discussing Domenic's concerns listed here: tc39/proposal-global#16 )

WH: How does this work across realms? The global object is a funny thing, as depending on where you evaluate it from, you may get different ones. If the global object is a proxy, is the system object also a proxy?

MM: The System object is very much like the Math object

WH: In an environment with multiple realms, there will be multiple System objects.

DD: (draws diagram to explain WindowProxy)

AK: Is this relevant to the System.global discussion?

JHD: I'll reiterate that this is not adding a new capability, as you can use the Function constructor; this just gives a way to do that without eval.

DD: Actually IE/Edge is restricted in a way that I don't understand for calling the function constructor in some ways

MM: This is one case where it's been hard for me to contribute to the web side of the standards world

BE: Ultimately this is about things like window.setTimeout (with a string so it will do eval)? Or what situations?

DD: Even executing a closure.

DD: WindowProxy is there so that, if you navigate a frame within another frame, the "window" object of that frame stays the same identity, so it is a "proxy" to an inner global object which changes on navigation. There's no way to access the inner object from within script.

JHD: Regardless of WindowProxy, System.global returns the global object, the same one that's accessed through 'this' or whatever else.

DH: Yes, this is the thing in the space of globalness that's relevant.

JHD: So we need a way to access the global 'this' value, a way that's the same across all environments. The function constructor can't be called from CSP. So we have two options--the bare 'global', or System.global. I haven't found anyone do typeof global

BF: Browserify's wrapper uses typeof global

JHD: But actually everyone uses 'typeof process' together with that when detecting Node-ness.

AWB: Two other options for names: Object.global

MM: I veto that as it would violate authority separation. I want to separate authority-carrying objects from non-autority-separating objects.

DD: But Object.proto is Function, which gives you the authority to get the global object anyway.

MM: Function and eval are evaluators; CSP gives you the option to turn off evaluators. Any other environment such as SES/frozen realms has to intervene in the evaluators in order to constrain the scope of the evaluation. In any such environment, the function constructor has to be sanitized.

YK: Doesn't that mean that we don't currently have authority separation, and you already have to do some work for this?

MM: We've addressed current pain points; let's not add to the burden.

AWB: A lot of this seems to revolve around the function constructor. Another place to hang this would be Function.global.

MM: Let's not spend time on things that are strictly worse

JHD: Mark has argued that this cannot be a global variable so that it's more easily secured.

DH: Sounds like a good time to bring in the Realms API and the global scope contour, which introduce additional concepts that want work in the language. It's an open area for discussion, where we might want to expose the actual current realm.

AK: There's something special about global. There's already three ways to access this thing; adding new ways is sorta bad. We're not adding a bunch of things; this is just accessing one thing.

MM: Right now, none of the ways of accessing global are not in the ECMAScript spec, and it's a beautiful thing that the boundary between the ES spec and the host corresponds very closely to user-mode computation and system mode computation. ES standardizes no way to cause effects on the outside world; the host provides bindings on the global object to cause effects on the outside world. Because the other things are put on the global, the global itself should be considered a host object that provides access to these things. Because there is no binding to the global object, nothing grants authority. There are several future proposals which do things like that.

AK: We don't have any of those. Global is special. There is some advantage to making the name short. Let's say it doesn't set a convention.

AWB: This should be a built-in module

JHD: So far, every time this came up, we said that we don't want to block it on this; once there's a standard modules proposal, we can consider this.

DD: We have a strong precedent for just calling this global. I want to understand your objection, Mark. It sounds like you're saying, let's not set the precedent of exposing a power object, when it's already exposed in reality in so many ways.

MM: Because it's not in scope in the ES spec, an environment could claim conformance to ES without exposing this.

DE: It is in the intersection of the various popular embedding environments, however.

JHD: I went with System.global because of the nonzero compat risk of bare 'global'. However, I haven't found any concrete compat risks. The second reason is that Mark thought it would help restrict authority to put it under a namespace.

YK: SES already has to care about this kind of thing.

MM: We currently have a whitelist in SES. global is not one of them.]

JHD: So if you're OK with not adding a global, you don't have to do anything to SES?

MM: I'm concerned about the maintenance cost and initialization time. Spec changes cause SES to trail, which users find painful.

JHD: But sounds like SES users will be protected anyway

AK: The difference between other things considered to add to System, Loader, etc and global is that they add new capabilities, whereas global does not add a new capability. It's just exposing an existing thing. Therefore it doesn't need to be added in a particular namespace, and doesn't set a precedent.

MM: I hope that frozen realms will be added and hide the global object.

JHD: It sounds like the requirement that it be under a namespace is not very strong, simply a preference

MM: "simply a reference is too weak. The issue of distinctions and psychological burden and precedent setting are pretty important.

DT: You're talking about the burden on developers?

JHD: I agree that they're real issues, but users already have the burden of having this reference.

YK: Given that you expose the global object, seems like it doesn't give a new capability.

MM: I'll have to think about this, but I can't approve that as a sound choice at the moment.

JHD: If Mark were to agree to Yehuda's point, if we changed the name to 'global', would anyone object to it with the name simply 'global'?

DD: I'd prefer 'self'

CM: no self

DD: Would prefer self

AK: 'global' seems fine. Most people don't seem to want 'self', Domenic.

YK, AK: This doesn't give any new capability as

JHD: Sounds like the next steps are for Mark to think through Yehuda's objection and see if he can support bare 'global', and for me to follow up with Mark, Dean and <who?>

Conclusion/Resolution

  • Remain at Stage 2

10.ii.b Template literal revision to stage 3

Tim Disney

tc39.github.io/proposal-template-literal-revision

Reviewers: Mark Miller and Waldemar Horwat

TD: (recap) w/ tagged template literals, escape seq. illegal. Changes seek to allow

TD: Approval Stage 3?

Conclusion/Resolution

  • Stage 3 approved

9.i.i ECMA402 formatToParts

Zibi Braniecki

ZB: Have implementation in SpiderMonkey, looking for a second implementor to proceed stage.

DE: To help formatToParts to Stage 4, ideal to upstream to ICU

CP: upstreaming to ICU should not be a requirement

AK: V8 not waiting for Stage 4

YK: The chicken-egg problem is about unflagging, not implementing.

ZB: Hoping Chakra, JSC, or any would implement

DD: What is the rush?

ZB: Not a rush, but the proposal has been ready for half a year. This is the last change that remodels the API. Everything else is new editions. This change opens abilities for cleanup.

YK: My opinion is that we've met the criteria

AWB: Do we have two implementations?

ZB: Yes

AWB: Compatibility issues?

ZB: Shipped in SM behind flag

CP: There are alot of new Intl features that need formatToParts

DD: They can just be dependent

EFT/RW: That's bogus.

AWB: There is experience from significant usage? Want to hear about that

ZB: Used in consumer facing product, Panasonic TVs running FirefoxOS. Proven that necessity to format is satisfied by this API.

AWB: With this exact proposal?

ZB: Yes

Implementations:

  • Intl.js
  • SpiderMonkey

ZB: The only feedback we've had is that developers want it in other browsers.

DE: Need to forward that feedback to other browser vendors

ZB: Want to plan for ES2017/402

RW: What is 262 cutoff?

BT/AWB: January/March (January for opt out, March for absolutely latest)

WH: I personally think you have enough implementation experience to advance to stage 4 now.

ZB: Can we advance to stage 4?

AK/DE: Some cases need 2 or more browsers, but this is not one.

Conclusion/Resolution

9.i.j ECMA402 Intl.PluralRules

Zibi Braniecki

ZB: Can we advanced to stage 3?

ZB: Both reviewers (CP and DE) have finished the review!

CP: Thumbs up!

DE: The spec text is complete. No worries in terms of performance and memory allocation.

ZB: All data needed for PluralRules to function are already in place, and used by Number and Date, no extra data is needed.

Conclusion/Resolution

  • Stage 3 Approved

10.i.a Require Unicode 9.0.0

Brian Terlson

Patch: Require Unicode 9.0.0 instead of 8.0.0

BT: We can update every year, or change language

EFT: "use latest"

AWB: Normatively referencing a spec with no version means "the latest"

BT: There are no changes in 9.0.0. Committed to reviewing changes each year.

RW: The 402 editor will have to do the same task

(agreement)

WH: New Unicode case mappings might cause \p{} (and especially ^\P{}) problems analogous to the \W problem we recently encountered.

BT: This won't be added in the future, but they can't be "fixed" because they can't break compatibility.

DT: Should the requirements be clear for ES implementations?

BT: risk w/r to breaking change updating Unicode, larger possibility with \p

  • Unicode is reluctant to touch case mapping
  • characters might move

DE: But these tend to be bug fixes?

BT: Still a risk of a breaking change

Conclusion/Resolution

  • Do not merge the PR
  • Use language for "the latest" ie. unbounded reference
  • This should be applied to 402 as well

10.ii.c trimStart/trimEnd

Sebastian Markbage

SM: change from "trimLeft" and "trimRight" to "trimStart" and "trimEnd". Put an "alias" in Annex B?

SM: Web compatibility risk: the names of the functions changes.

DE: We changed a separately named Date method to an alias in V8 and didn't experience any web compatibility concerns, so I wouldn't anticipate any web compatibility issues here.

SM: We have other aliases in the spec; I was trying to follow existing precedent

JHD: e.g., Array.prototype.values/[Symbol.iterator]

AWB: If there was evolution of mainstream functions, the web compatibility functions

DE: Code is likely not relying on the name, likely not much risk

SM: Need reviewers

Jordan Harband + Daniel Ehrenberg

AWB: Spec for trimLeft/Right is the same as trimStart/End?

JHD: Exactly the same, only a name change

MM: That's the breaking change?

JHD: Yes, otherwise there is no issue

Conclusion/Resolution

  • Stage 2 Approved

Array.prototype.values

Adam Klein

AK: We tried shipping Array.prototype.values and it broke some random Microsoft property, with the "'values' in" pattern

BT: We shipped it

EF: We didn't ship it on Release, but it's on Beta.

AK: Safari shipped it, but it seems like people who depend on Chrome are not shipping it. There's a switch between an object with a values property and an array. This is a general problem with adding a property to existing objects.

YK: We could add a function to get the values out.

AK: Chrome is not going to ship this any time soon, as we tried a year and a half ago and it didn't work, and we tried now and it didn't work.

AWB: This isn't a web interoperability issue; it's a Chrome interoperability issue.

AK: I'm not so concerned about it because it's not used so often, but it might make people sad that it's not shipped.

AWB: This isn't a new thing in the world of JS, but eventually everyone converges to standards, see IE/Edge

AK: Please do not add any more things to Array.prototype

BE: ES4 tried to do namespaces. Modules should give us a way to do this. I'm agreeing, we can't really extend things too much.

RW: what software?

AK: CRM Dynamics 2013

BT: It is fixed, but people don't update their on-premises software. They hire a contractor to install it, and then the contractor walks away. We tell them just use IE11 rather than Edge. You can configure a group policy to open certain pages in IE11

Conclusion/Resolution

  • No change; Firefox will proceed with caution in shipping values.

10.iv.a Class Field Initializers: this semantics

Jeff Morrison

jeffmo/es-class-public-fields

JM: main issues

  • Contextual things in the initializer scope.

  • Initializers execute at the time of the last

  • static field initializers are executed as the last step of class definition evaluation, need access to the class name binding itself.

(discussion of the scope of initializers)

JM: What should be available inside the initializer?

  • Banning arguments, new.target (b/c unclear) -- these are static semantics errors when occurring literally, and undefined in direct eval
  • Allowing this and super property access

YK: It would be confusing to have the old enclosing copies of new.target or arguments inside of the initializers, which run later

AWB: Can't you write "arguments" in computed properties?

YK: We discussed this in the context of the cross-cutting class proposal with Brian

  • You might want this in a static property to refer to the class you just created

JM: There have been issues created in the Babel tracker filed about the scoping of this

AWB: In a static method this refers to the constructor function

  • The constructor function that the static property is defined on

AWB: A consistency for static initializers for the left and right hand side of initializers would be to be "the same as in a static body"

JM: open q: "Do we permit or ban new.target or arguments in the right hand side of initializers?"

YK: This becomes tricky because some people expect that a field referecnes ambient bindings, but it's easy to get confused if you treat the initializer as a method

AWB: These initializers are very shorthand for a function, which always has new.target

MM: In favor of banning

AWB: A usecase is a static method on subclasses that filters the initializers, as called from a superclass constructor. In that case, you want to call |new.target.initializerFilter()|, and so want new.target to work

YK: Even though you can construct models which are consistent about which is which with new.target and arguemtns, it's equally hard to construct one that is unambiguously clear which one you are referring to

YK: This isn't a catchall; there will still be imperative cases that benefit from being written in the constructor

JM: If we ban them now, we can always add them later.

JM: We also need to decide what to do with eval('new.target')

MM: Presumably if it's an early error without eval, then it will throw early during the eval as well

(discussion of alternatives)

MM: Because this is a convenience tool, we can ban eval without loss of expressiveness. It's just a loss of convenience

DH: On instinct, this scares me. Just because we can't come up with a usecase, doesn't mean that something won't ever come up

WH: How deep would the direct eval ban go? Expression, subexpressions, within arrow functions inside subexpressions, ...?

DH: banning direct eval is hard, because it's undecidable whether it's direct eval

YK: Yeah, we'd have to ban the entire class of things that could wind up being direct eval

MM; The only reason we're allowing these outside of the constructor at all, is for common well-behaved cases

AWB: This of this as shorthand for function. If it was a function, all functions define new.target. When invoked you get undefined. Functions have arguments. There are no functions. If you just treat an initializer like an anonymous function, then you get exactly everything falling out

DE: If you treat it like just a method, then you get everything you want

AWB: This avoids a laundry list of special cases

KG: What about statics? The easy corolary is that for statics, it's an anonymous static method.

YK: This also allows for sane semantics for this

KG: (whiteboard)

class Base {
  prop = new.target.filter ? new.target.filter(val) : val;
}

class Derived extends Base {
  static filter() {}
}

AK: Does this restrict impl ablitie to optimize away? No, we should be able to statically determine whether eval or arguments are possible.

EF: This is a simple front-end optimization.

Consensus: Initializers run with the semantics of individual anonymous methods with no arguments being run on the class. That explains the scope of this and super property access; new.target would be undefined, and each would get a new empty arguments object.

JM: Do properties get created with DefinePropertyOrThrow() or Set()?

(whiteboard)

class FooText extends TextNode {
  textValue = "asdlsk";
}

YK: Users would likely expect to get a Set; most users don't understand setters, and would expect that setters are always called

WH, MM: Would be really surprised by a Set in this example. The intuition is for initializers to use define.

JM: You could phrase this either way; either it's a hazard, or it sets the expectations that users can depend on a predictable DefinePropertyOrThrow.

WH: The reason why Set doesn't work is that it's not extensible to const, to typed properties, all of these can only be done on DefinePropertyOrThrow

textValue = "adadad"

^^^ Authors don't immediately recognize that the difference between Set() and DefinePropertyOrThrow()

WH: Can't use Set() to define const or typed properties. Only DefinePropertyOrThrow will work.

MM: A frozen data property, overriding with Set() will throw

JM: Having spent some time on this, I think neither is more intuitive than the other. People are very split on this. So as an argument for which is more intuitive, that's a wishy argument. We should go based on what is more useful.

AWB: If you define a method named textValue, you can't

BE: = looks like Set

AWB: So we should use colon

YK: Colon is reserved for type annotations

BE/WH: the only robust semantics is DefinePropertyOrThrow()

WH: Only DefinePropertyOrThrow will work across future extensions, for const properties and typed properties

  • evaluate the type, around time of initializer, can't create it and later change type, so it MUST be created with DefinePropertyOrThrow()

SP: How is this conflated?

MM: The idea that an initializer does a Set(), but a const does a DefinePropertyOrThrow() is just (confusing?)

MM: We already have in ES6 practice for how to initialize objects imperatively, with this.textValue = "asdf" inside the constructor. That's imperative, that does a Set(), it has all the properties that Yehuda is advocating. Any proposal that adds new syntax should, to justify the cost of the new syntax, it should have less overlap with something you can easily say already.

this.textValue = "...";

...is a Set()

YK: This is shocking. That means that you are saying we shouldn't have symmetry

MM: I value symmetry, but I don't see a symmetry argument. Leaving aside BE's point about the token, for object literals, all properties in object literals are initialized with DefinePropertyOrThrow

YK: But most people will have the imperfect but good-enough mental model to view this as a desugaring to this.textValue = ...

BE: This isn't true, as object literals already do something different compared to manipulating the object, if you put a setter on Object.prototype

YK: But that is suprising to many useres

AK: What about developers of other languages who define fields and expect those to not trigger setters (as in other languages, where setters don't happen when you declare fields)

MM: This is just like an object literal. Writing object literals has the same problem.

YK: That's different because object literals don't have superclasses. People don't use proto: very much

BE: What's the robust, future-proof semantics? Seems like DefinePropertyOrThrow, as Waldemar says.

DE: If you subclass an HTMLElement and try to define an onclick, that would be fired either

JM: What about :=

SM: Having setters already be there is one use case. The primary use case is turning an existing property into a setter or getter, to shadow something else or make something lazy. If that's the upgrade path, then this will break.

DD: That's a good point; people do deprecations by adding setters or getters, and that would fail because it would just shadow

MM: If the semantics of this is Set, I would ask, what is the added value of the proposal as a whole such that the proposal pulls its weight. You could get these semantics just by writing the right lines in the constructor.

DE: Good from an optimizability stand point. We've been encouraging people to be explicit about properties on this by adding them all in the constructor, assigning undefined if necessary. This is a nice synaxt for that.

WH: Using Set() is dangerous, if derived class has foo, exposes you to a super class that didn't have accessor foo, which is later added.

YK: Lots of classes which are designed to be subclassed assume that they can intercept Set()s

DT: Initialization in C#, Java, etc is explicitly settting up the world and invariants aren't there

DD: For us it's different, because super has already returned, etc

DT: Using DefinePropertyOrThrow is good because it'll give us that capability from other languages, where you add the properties without invoking setters.

SP: In the current proposal (with Set), it's the same as doing the code in the constructor, so the constrained DSL is nice because it is not so order-dependent, right?

JM: Sounds like we won't resolve the issue in this meeting; I'll work with some people offline to come to more of a conclusion on this.

JM: The last open question: For fields that do not have an initializer, these implicitly initialize to undefined, not copying this.x = this.x as previously. I went back and forth on this; one of the reasons I was against this is that I was concerned about shadowing the same-named property on the parent class. But what convinced me is that, presumably, if you put that declaration there without an initializer, you would intend to initialize it later at some point, in which case you would be shadowing the parent property anyway. So the expectation is that, when you put the field there, you will be shadowing the field above it. So the initialization happening in order makes sense.

class FooText extends TextNode {
  textValue; // textValue = undefined;
}

WH, AWB: Good.

AWB: In lexical scoping, we decided that the same name in the same scope would always refer to the same binding. The analogue here points in this direction as well.

JM: Cases where it's useful to define the value of a child in terms of the parent property value...

this.x = this.x + 1;

AWB: Suggest creating the fields first, presumably undefined, then assign.

WH: Separating creation from initialization is not future compatible with const or typed properties either unless we want to do something equivalent of a TDZ for properties, which I don't.

WH: Back to JM's original question, the only sensible thing for a field declaration without an initializer to do is to create the field with the initial value undefined.

DD: left hand side of computed property evaluates once (for definition), the right hand side many times (for instantiation)

[this.counter] = this.counter++;

JM: concern about syntax, further syntax might help solve, will consider

AWB:

DD: It should be consistent with fields

JM: I see the analogy with methods as being stronger. Anyway, most use cases will be with Symbols.

AWB: Want consistency across the whole construct, whether method, field or getter/setter

AK: This isn't thought of as a statement, but rather as a declaration, so the evaluation of the computed property names gods with the other declarations

(discussion re: transpilers)

DH: "identifier : identifier" currently means type annotation

w/r to this ^^ tc39.github.io/ecma262/#sec-forbidden-extensions:

The Syntactic Grammar must not be extended in any manner that allows the

token : to immediate follow source text that matches the BindingIdentifier nonterminal symbol.

JHD: Babel is doing fine with Set, this scoping, etc, and we should take that as a datapoint. No user complaints.

MM: Should the properties be defined as configurable or non-configurable?

JM: Currently it creates a non-configurable property with DefinePropertyOrThrow

YK: Seems strange why we would do it differently from methods

MM: I strongly prefer non-configurable. We already have an imperative syntax for imperative initialization, properties that are configurable and disappear. The time-dependent nature of configurable properties don't give you as many guarantees. Non-configurable properties lets you minimize gratuitious differences with private state and get static analyzability and static shape. The behavior of private fields is more like a nonconfigurable property than anything else.

AWB: I support your position, but in addition: one of the advantages of this new syntax, is that it allows to declaratively define the shape of the object.

  • Value in readability
  • Make non-configurable is a powerful value

AWB: what happens when a super class has already defined one of these? When they are configurable?

MM: Silent replacement

  • Prefer: two declarations of the same own property, an error.
  • Set() alone doesn't produce an error, DefinePropertyOrThrow() alone doesn't produce an error.

DE: super constructor might return a Proxy

EFT/AK: Implementors can't infer more about shape than before

JM: Objections to Stage 2?

AWB: I want to see this and private fields merged. I don't think we should advance either on their own to stage 3.

Conclusion/Resolution

  • Initializers run with the semantics of individual anonymous methods with no arguments being run on the class. That explains the scope of this and super property access; new.target would be undefined, and each would get a new empty arguments object.
  • No consensus on Set() vs. DefinePropertyOrThrow()
  • A field with no initializer should create the property with the value undefined
  • No consensus on configurable vs non-configurable
  • Revisit initializer token choice of =
  • Stage 2

10.iii.c [Nested import declaration](

benjamn/reify/blob/master/PROPOSAL.md)

Ben Newman

BN: Potentially relaxing restriction that import can only appear at the top level.

BN: proposal would allow imports that are nestable; hoisted (declarative over imperative); lexically scoped; sync evald; back compat.

BN: We have been shipping this to the Meteor community in a transpiler context. The semantics are more subtle than you would expect to allow, due to the subtleties of modules. They are synchronous (hoisted to the top of the scope) and backwards compatible.

MM: [clarifying that bindings are immutable on the import side]

YK: [clarifying that currently proposal is transpiled to commonJS require]

… discussion about the spec; request to skip the spec discussion at this stage …

AWB: How about we consider these to be ordinary lexically scoped variables?

WH: If I sit inside a loop, importing a module mutiple times, will I get the same module namespace object?

BN: Yes. In subsequent iterations, it doesn't get imported again

WH: Is the module specifier still restricted to only being a string literal?

BN: Yes.

DH: in this proposal, no matter what, all imports will be loaded beforehand. it's only that evaluation will be deferred until it reaches that point in the code.

AWB: do you hoist evaluation as well as instantiation - i would expect that hoisting for consistency with top-level imports

BN: the ability to have nested imports gives you a tool to control relative execution of import declarations to other statements

WH: Yes, that's the Optimistic Imports example from the proposal.

YK: DH's point is important. If you want predictability, you do not want interleaving.

BN: Modules get all loaded before the program starts. Their instantiations are done as their blocks are encountered in the program.

WH: So then what happens if a module is missing when being loaded? How do Optimistic Imports work?

BN: necessarily an error if it fails to load.

BN: … talking about a use case for cross-env code with conditional imports … if it turns out that the fetching of the module source fails, it is entirely conceivable that the dev knows this was a possibility and that that import is inside a conditional block that prevents it from evaluating

  • so i think it's less fatal for the fetch to fail.

YK: an important use case for this is "if i'm in env X, import stuff for env X"

DH: proposal: we unconditionally do all the fetches, but if any fail, we don't actually fail - just hang onto the error for later. and only if control flow reaches the point where it's needed, does it end up being an error. iow, if you only have conditional imports, failures will not create a compile time error, and only create a runtime error when the module is needed and missing.

AWB: consistent with the current spec.

AK: changing what used to be early errors into not-early errors.

AWB: i mean consistent in that it treats each block as if it's its own module.

YK: ?? conditional importing means the dev knows it's benign if it's missing, and can work around that.

BN: … explaining "isolated scopes" example … ability to reuse identifiers in the same file, but in separate scopes. With top-level, you need slight identifier variations.

SP: also refactoring hazard - if the imports are in the describe, it's easier to split up large files without breaking things.

BN: in top-level model you still have to do all the same fetching

CP: at what point in this program is the error triggered? we intentionally chose declarative import evaluation as well as initialization/loading.

BN: the specific "it" test in my example will fail if the import nested inside it fails to load.

BN: it should fail every time it's import is attempted

DH: it should be possible via the registry to clear things out and make it possible to retry, but only in a staged way - ie, you have to kick off an evaluation, not in the middle of a module.

BF: in node, if it evaluates, it's put into the cache; if it fails to evaluate, it's not put into the cache.

… discussion about entire dep graph being resolved before any evaluation …

DT: … general argument that nested imports would have to be VERY compelling to make it worth it …

AWB: what about imperatively using a dynamic import API?

DH: loader API does not let you statically express dependencies, so we talked about a syntax that allows dynamic async importing

… more discussion ?? …

DH: inherent conflict with top-level await

BN: I think the dynamic syntax you're proposing is essential for top-level await. what would happens with current import if you pull in a module using top-level await?

CP: top-level import would handle it

DH: essentially forks the world - ie, "modules that can use top-level await" and "modules that can't"

BN: still some motivating examples worth talking about

BF: a point: top-level await is going to pretty much wreck node's sync loading anyways

BN: if top-level await turns out to be infeasible, then the conflict here is moot, but still worth talking about

YK: my concern is that it makes loading unconditional + evaluating conditional, and i think conditional loading is important too

BN: skipping over "lazy eval" claim. will note that in node, which has sync i/o, pushing requires into functions has helped startup perf (likely from deferring the i/o)

SP: depends on the complexity of the file you're importing

SM: biggest perf problem at FB is parsing and initialization. we load everything and only evaluate the things we need. we can't switch to modules without lazy eval + lazy loading.

BN: i think it will not interfere with lazy loading.

BN: if you treat all module identifiers the same, then you don't have to parse the whole file, you just have to tokenize it and look for "import" tokens.

EF: i think you grossly underestimate the costs involved.

… discussion about tokenizing vs parsing; costs thereof; etc …

BN: in my naive understanding of tokenizing and parsing, you could tokenize, iterate, locate import, locate the possible path - then optimistically parse that path whether it's a module or not.

AK: unless you're talking about throwing away all module early errors, you need to know the exports, so you still have to parse. your approach only would allow easier fetching.

BN: if i'm wrong about the tokenizing trick, it still doesn't matter where the import declarations are

YK: i think the point is that if it turns out that conditional import …

SM: what matters is "do you do the fetch if there's a syntax error"

CP: Do we need to have a user make a change to allow for this tokenizing optimization?

BN: The optimization is orthogonal

DH: He means deferring evaluation

BN: That seems unsafe to me.

BN: Colocating imports and code should be good long-term for code hygiene because it should keep the things together and help you as you move the code around. And of course you can keep putting them all at the top level if you want.

BN: Further justification: Put an import in a try/catch block in case you have fallback behavior.

SP: But what if it's not the first time? This scares me. You don't get the chance to execute your fallback behavior.

MM: Maybe you should remember the throw and rethrow if it failed.

CP: You were saying that it should go to the top

BN: To the top of the block. It will still throw from within the try block.

AK: To me, this looks like a nested module. It seems like it would be a module in the tree which fails.

BN: Another benefit is dead code elimination--you can avoid running the code by importing only when needed, and this then doesn't run the top-level statements.

AK: Dead code elimination will be approximate in JavaScript. It couldn't be done by implementations, but could be done by preprocessors which are OK with changing semantics.

MM: Is it valid to eliminate the fetch?

BN: Technically these change semantics, but may be OK for the application.

BF: Module resolution may not include fetch; for Node, things will be pre-populated

YK: We did a lot to support the web's asynchronous fetching.

BN: Yes, we needed to support browsers. Nested import declarations seem problematic mostly because of the browser and asynchronous fetch.

BN: I have a grammar in the proposal. Import is not allowed in non-modules. There is a PR, I invite people to participate there. Nested imports from scripts are prohibited with static semantics.

BN: We have settled on declarative imports, hoisting them. But nested imports give you a tool for doing imperative imports, though no deferred fetching and specifiers are literal

BN: Stage 1?

DH: Suggested area of exploration: await import

async fn() {
    await import {x} from m;
}

AWB, YK: We should merge this group with the loader group to come back in a few moths.

AK: I'm surprised you're not upset about it being a promise.

DH: But the Promise is not reified

BN: I would prefer synchronous semantics, if possible, but we could live with this. For one, it would be nice to run successive import lines in parallel.

Conclusion/Resolution

  • Does not reach Stage 1; a synthesis proposal will be pursued at a future meeting. Remains at Stage 0.
# Rick Waldron (8 years ago)

July 28 2016 Meeting Notes

Brian Terlson (BT), Michael Ficarra (MF), Jordan Harband (JHD), Waldemar Horwat (WH), Tim Disney (TD), Michael Saboff(phone) (MS), Eric Faust (FST), Chip Morningstar (CM), Daniel Ehrenberg (DE), Leo Balter (LB), Yehuda Katz (YK), Jafar Husain (JH), István Sebestyén (IS), John Neumann (JN), Domenic Denicola (DD), Rick Waldron (RW), Stefan Penner (SP), Jonathan Sampson (JS), Caridy Patiño (CP), Sam Tobin-Hochstadt (STH), John Buchanan (JB), Kevin Gibbons (KG), Lars Hansen (LHN), Tom Care (TC), Dave Herman (DH), Bradley Farias (BF), Kris Gray (KSG), Adam Klein (AK), Dean Tribble (DT), Eric Faust (EFT), Jeff Morrison (JM), Sebastian Markbage (SM), Saam Barati (SB), Kris Gray (KGY), John David Dalton (JDD), Ben Newman (BN), Morgan Phillips (phone) (MP), Shu-yu Guo (SYG), Paul Leathers (PL), Ben Smith (BS), Zibi Braniecki (ZB)

10.ii.a Shared Memory And Atomics

Lars Hansen

tc39/ecmascript_sharedmem

LHN:

Agent Semantics

Blocking: an agent can block waiting to be woken without rturning to its event loop

Web awareness: an embeddinging can deny some agents the abiluty to block (eg. browsers man thread)

Forward progress: agents must eventually advance if

All agents die at the same time

SharedArrayBuffer

  • New Data Type
    • Like ArrayBuffer

      • map TypedArray and DataView onto it
    • Unlike (see slide)

Sharing Memory

Atomics

The global Atomics namespace has static methods that operate on TypedArrays

Atomic access:

  • load
  • store
  • add
  • sub
  • `and
  • or
  • xor
  • exchange
  • compareExchange

BF: Is it possible to have another worker store between wake

EFT: Yes

DT: A spin instruction that doesn't spin, on x86?

LHN: Yes

  • Investigated pause as a lightweight wait, that wouldn't go into a spin, but
  • wait for a short time
  • if hot wait, could've used pause before going into a wait
  • you could use pause instead of direct into wait

(I'm not sure I captured this as well as it could be, wuold appreciate more eyes/brains to revise appropriately)

Memory Model

... see slide

Challenges

... see slide

Opportunities

ES is "easier" than C/C++

  • Performance demands slightly lower
  • Shared Mrmory sep. from non-shared
  • Only flat shared memory, no pointers or objects

... see slide

Two Level memory model 1

Conventional axiomatic high level model

  • Defines sync accesses
  • sync order
  • "happens=before" relationship

... see slide

Two Level memory model 2

... see slide

Synchronization Order

... see slide

Viability 1

... see slide

Viability 2

... see slide

LHN: WH found an important bug in the memory model's definition of viability that causes the synchronization order to not be well-defined. Without a well-defined synchronization order we don't have a workable model. This will require a rewrite using an operational approach instead of the current two-phase viability and synchronization approach.

LHN: [talking about slide] Races "leaking" into the memory model of the sequential language.

WH: Agree that they don't leak (and must not leak). The price we pay for that is significant loss of opportunities for optimizations. It remains to be seen whether that's a reasonable price, but I assume it is for now for the purposes of this proposal.

LHN: [talking about slide] Security issues are the "cost of doing business" of shipping shared memory, at least according to one major browser vendor. Mozilla is less sanguine about that.

MM: Is there any way to ameliorate this?

LHN: Add a switch to settings to turn multithreading off.

(discussion, re: changes that need to be made)

WH: The memory model will need to be rewritten.

?: Why rewrite? Can't we just fix the bugs that WH found in the presented memory model?

LHN: What I just presented is the new memory model I'm developing to fix the bugs, not the one currently in the spec.

  • Avoid a circular

WH: What was in the spec had fundamental incorrect assumptions such as defining viability as a separate phase before synchronization, or the ability to put all memory accesses (including non-atomic ones) into a global total order, which just isn't true.

WH: We all agree on what the simple cases where everything is synchronized properly ought to do, such as what happens in an atomic load that sees the result of a prior atomic store. It's in the other cases that need to be nailed down where the big memory model issues lie.

SYG: How to test?

  • An impl to be compliant, must be able to observe the memory model
  • Is that possible?

BS: without particular axiom, here is X that breaks.

SYG:

STH: Write the memory model, rep. all the legal executions. Run X times, ensure that all

SYG: How to test the actual implementation

Conclusion/Resolution

  • API freeze granted?
  • Stage 3 after Waldemar is satisfied with rewrite of memory model

10.i.b Disregard lastIndex for non-global non-sticky regexps

Leo Balter

PR from Claude Pache tc39/ecma262#627

LB: The change is: "don't do the lastIndex step unless isn't actually necessary" tc39/ecma262#625

DE: Global regexp don't make sense when frozen

  • Some programs freeze regexps, unsure why.
  • This is in use, received bug reports

(discussion, re: how long this might've been allowed?)

AWB: user freezable properties and strict mode introduced in ES5

DE: Doesn't make sense to read/write lastIndex unless actually necessary.

AWB: Could break something

DE: True

  • The plan is to attempt the fix, ship on chrome/canary and see what happens

AWB: (recapping the proposed fix)

LB: This PR also adds a change to avoid get and ToLength operations on lastIndex for the same regexps. A poisoned RegExp lastIndex property wouldn't affect it.

function test(rx) {
    rx.lastIndex = { valueOf: function () { throw "ok" } }
    try {
        rx.exec('foo')
    }
    catch (e) {
        if (e === "ok")
            return true
    }
    return false
}

LB: After this patch, a test(/a/) should return false.

MM: That does not only address the web compatibility issue, but does a clean-up on the lastIndex.

Conclusion/Resolution

  • Merge it
  • Implement in canary and report what happens

10.iii.d Object.shallowEqual

Sebastian Markbage

sebmarkbage/ecmascript-shallow-equal

SB: Problem...

Memoization

... see slide

function eq(a, b) {
  return Object.is(a, b);
}
function memoize(fn) {
  let lastArg, lastResult;
  return function(arg) {
    if (lastArg !== undefined && eq(lastArg, arg)) {
      return lastResult;
    }
    lastArg = arg;
    lastResult = fn(arg);
    return lastResult;
  };
}
function calc(obj) {
  return obj.x + obj.y;
}
let memoizedCalc = memoize(calc);
let obj = { x: 1, y: 2 };
let res1 = memoizedCalc(obj); // slow
let res2 = memoizedCalc(obj); // quick
let res3 = memoizedCalc({ x: 3, y: 4 }); // slow

SM: Would like to be able to compare only the own property values

WH/MM: (discussion about concerns and objections that have been previously discussed)

YK: Does this anticipate being faster on value types?

WH: As an evil villain I love the ability this might give me to compare the internal variables captured inside closures [scary emoji]. Mwa ha ha ha ha!

MM: That's one of the issues I had raised.

YK: ?

SM: Most of the time, returns false.

YK: (equating semantics to memcmp)

AK: No, memcmp is just implementation suggestion

MM: The semantics:

  • If the answer is true, guarantees follow
  • If returns false, no guarantees follow

YK: The guarantee using Object.is?

MM: Uses identity

SM: Compare objects across realms is also a question

YK: Ok, the intended implementation is memcmp

(confirm)

FST: There's a browser war on. If [browser x] returns true 30% of the time in this case, then I must return true at least 25% of the time.

AWB: Are there other approaches you could use to obtain much better performance?

YK: The whole thing is a performance detail which we don't really specify. There are some things that look like value types but in fact have expensive === operations.

AWB: We chose to have multiple representations of things like strings for performance reasons. Now they will cost us. It's hard to specify semantics.

FST: As a browser vendor I don't want to constrain otherwise efficient representations due to the performance implications of wanting to return true from this feature.

MM: This is affected by the transposed implementation of weak maps.

WH: And it leaks information about what's in the weak map.

MM: You'd want closure state to not be part of the comparison.

MM: We want to store private state in object slots, but we want object scans to not reveal anything about the private state.

FST: Implementations will need to distinguish different kinds of internal slots anyway.

WH: This presents similar issues to NaN comparison, but for strings. As the example in the presentation showed, now you can figure out the pedigree of whether a string was constructed in one piece or as a rope by something on the other side of an abstraction boundary — something that must not be leaked for security reasons.

BE: leaking string implementation details (Rope vs. Flat representation) has been constructive for Heartbleed-like security attacks in past.

STH: evidence of the code you've written being slow enough

SM: no evidence yet

AWB: Here's another path... bring the slow path code to implementors and try to optimize in the runtime. Then with this experience, determine a proposal for language or built-in library changes

SM: Will try

WH: Do implementations ever store hashes along with strings to be able to quickly determine that they are not equal?

FST: We intern some strings, but not all.

(discussion, re: hashing, string interning)

YK: MM, are you not worried about the moving gc leak?

MM: I am.

YK: Moving GC... do a comparison, it's true. The object is changed by gc, and becomes false

STH: No

EFT: If there is a concrete case that shows instability, we can explore

WH: Can discover if implementations do lazy string interning

MM: Do meet S1 criteria, but not worth trying to move this forward because this doesn't have a chance of advancing further. Identified real issues, that we can find a way to address. Sam's suggestion might be the only viable

STH: Actual shallow comparison, implement that in VM and work on optimizing.

AWB: Essentially same as my suggestion

Agreement, but comments from implementors that I didn't quite catch

SM: Object.assign could be done much faster in VM, WeakRefs... Plausible to find other ways to accomplish same thing. Difficult reach non-leaking solution.

MM:

Something about exploring alternative solutions

It's hard to hear because they are across the room and basically mumbling as far as I can tell. Mark is facing away and it sounds like "mmph mm-mmmph err mmph foo sh mmph sh"

(discussing "fast")

YK: VM authors recognize security issue of fast

MM: How much slower would be an accurate implementation of shallow comparison be?

SM: Would it be possible to expose the ability to compare shapes [or use the shape as a key in a map]?

MM: The nondeterminism arguments apply to anything that assumes same shape.

Conclusion/Resolution

  • Explore STH/AWB recommendations

10.iii.b Promise.prototype.finally

Jordan Harband

ljharb/proposal-promise-finally

JHD: (presenting from the link above)

AWB: How would a user write something that is rejected from a finalizer?

WH: What does finally return?

JHD: A new promise

DD: Conceptually wrong to overwrite return values

YK: There is control flow model and have way to...

WH: How does this interact with thenables?

JHD: If the finally return value is a thenable that's resolved normally then it gets replaced with the prior resolved value.

WH: Does this introduce a notion of finally-able with parts of the system probing for the presence of a "finally" method analogous to what they do with probing for a "then" method?

MM/JHD: No, just like we don't have a "catchable"

JHD: (explanation of naming, can be reviewed in proposal)

BE: names are metaphorical and analogical, not only identical up to isomorphism; finally seems good to me.

  • Existing implementations noted as well

MM: Some "wrinkle" in Q?

JHD: Will identify and note if necessary

DD: Could be naming, ie. "fin" for ES3?

BE: promise'finally'

JHD: No conflict re: cancellable promises proposal

YK: Might be good to have finally in language, before 3rd state

JHD: Same

  • Devs can proactively use finally where semantics match

YK: Might be hard to convince that finally is the right thing to do

AWB: Why wasn't finally included in ES6?

YK/MM: The ES6 Promise feature was "maximally minimal", so finally, along with others, eg. queue, were postponed

JHD: Stage 1? Note that this meets the Stage 2 requirements.

JHD: Stage 2?

DD/DE: There are issues that need to be addressed in this spec text

JHD: changes needed in this spec, to reach Stage 3

  • PromiseReactionJob needs attention

MM: Want to revert my Stage 2 agreement...?

JHD: (cites Stage 2 from process doc)

MM: (something about Stages)

JHD: If I get Stage 2 now, I can work towards Stage 3 in September

(General discussion about process)

YK: We frequently have disagreements about the process.

DD: Disagreements on process aren't helpful

AWB: Don't wqant to jump feature two stages in one meeting

YK: The criteria is met

  • I want criteria that's objectively applicable

AK: The criteria is "there is spec text to review"

JHD: Since this was on the agenda for May, then everyone diligently reviewed—Right?

AK: There is no review requirement on Stage 2 spec text. Achieving Stage 3 requires review and revision, etc.

JHD: So, AWB objects to Stage 2 on the grounds that it's two stages in one meeting.

AWB: Won't block if the rest of the room wants to advance

WH: Have no objection to this, but in the future I'd love a prior notice on the agenda for any item that wants to jump more than one stage so I can look at it much more carefully before the meeting.

Conclusion/Resolution

  • Stage 1 approved
  • Stage 2 approved

10.iv.b Cancelable promises update

Domenic Denicola

Slides: docs.google.com/presentation/d/1kSY7X1ymw5f2oatDrZaMJh4Z_wpd0ynZIimhUyqhbrY/edit#slide=id.g15f86355f5_0_55

DD: Major change: third state

  • A new completion type is unable o achieve consensus
  • Concern:
try {
  f();
  g();
} catch (e) {
  h();
}

A new exception that is not an error: Cancel

  • Does not subclass Error
  • Branded with a [[CancelBrand]] internal slot
  • Does not get reported to the host
    • window.onerror
    • process.on("uncaughtException", …)
  • Does not get tracked as an unhandled rejection either
  • throw Cancel("message")

Making it easy to treat cancelations as non-errors

Bad code...

try {
  await fetch(...);
} catch (e) {
  if (!(e instanceof CancelError)) {
        showUserMessage("No data for you, sorry.");
  }
} finally {
  stopLoadingSpinner();
}

Proposal:

try {
  await fetch(...);
} else (e) {
  showUserMessage("No data for you, sorry.");
} finally {
  stopLoadingSpinner();
}

// Also, Promise.prototype.else

Addresses the new code, old code issue, because no old code will have this form,

JHD: (question about brand checks)

WH: Can you do try/catch/else?

DD: No

JHD: Any catch cancel?

DD: No, this is everything but

Cancel token’s cancel() always creates a Cancel

const { token, cancel } = CancelToken.source();

cancel("message");
// internally does: new Cancel("message") and stores

token.throwIfRequested(); // throws the stored Cancel

token.promise.then(value => {
  // value is the stored Cancel
});

MM: Then still invokes the second callback?

DD: Always has been

  • source of bugs
  • throws happen, people expect their catch handler to be called

MM: I disagree with your opinion on the usefulness of .then's second argument

DD: it's more of a power user feature.

DE: This works better with the two argument then. previously there was a back compat concern (with third state), and with this proposal, it's more compatible with 2-arg then.

MM: Having else in relation to then..,

Cut off by other members who are time constrained

BE: Is dependent on state of the stack?

DD: No

DE: Sounds like this is analogous to then/else, letting cancels propagate, where 'then' handles the next try and 'else' captures the non-cancel reject; I think this is consistent with the two-argument form

DT: A wants to suppress errors if A is being canceled, regardless of what B does. If B errors, it goes up to A and A can decide what to do.

DD: I recall this concern, I disagree that this matches all reality

DT: Back to try/else. Q: try this thing and my local token is cancelling, suppress error, otherwise...

  • Need

MM: The test: is it a cancellation?

DT: A cancellation is a fine way to implement shut down

  • Need to allow the shutdown, avoid thrashing

DD: Experience shows that it's important to suppress the...

DE: Sounds like the disagreement between Dean and Domenic is whether to just supress the one cancellation, right?

MM: Asking for: source of information is a distinct thing, expanding the syntax taking into account the token as a source of information.

DT: I'm saying we can get a syntactic form that can do both

DD: I'm only trying to address this problem,

DT: (describing example of cancellation where a download was stopped, but results in a parse error of the incomplete download the contents)

YK: hard to imagine a library creating a cancel token... (I missed the entire scenario, Dean started talking)

DT: I create a file and a cancel token and hand the file to the parser, then trigger the cancel token, which stops the parser. For example, stopping a page

DD: Stopping a page is a bigger deal

BE: (asking for summary of what needs to actually be address)

DD: The question is, is there an unobtrusive way to have syntax that provides the semantics that Dean wants?

DT: The Question: The indirect cancellation, does it turn into an error?

DD: Don't think we need to address the case of "buggy code"

  • Part of why no longer championing try/catch/else

DD: The concern is about calling into a library which, you cancel the library's overall operation, and it gives you an error rather than a cancellation. The conclusion is that that is very hard for the library to do; these syntactic affordances make it hard to do as you'd have to do a catch, followed by a brand check, which is intentionally hard.

DD: I'd like the committee's feedback on the full spec, which is now much smaller due to fewer modifications to promises, etc.

DD: Some more ideas on making Promsies more ergonomic: Make cancellation easy in async functions.

More Ideas...

  • Inserting cancelation opportunities into async functions

Simplest case, pass the token:

async function cancelMe(cancelToken) {
  doSyncThing();
  await doAsyncThing(cancelToken);
  await anotherOne(cancelToken);
}

What about uncancellable things?

With the current proposal...

async function cancelMe(cancelToken) {
  doSyncThing();
  cancelToken.throwIfRequested();
  await doAsyncUncancelableThing();
  cancelToken.throwIfRequested();
  await anotherOne();
}

Probably want...

async function cancelMe(cancelToken) {
  doSyncThing();
  await Promise.race([
    doAsyncUncancelableThing(),
    cancelToken.promise.then(c => { throw c; })
  ]);
  await Promise.race([
    anotherOne(),
    cancelToken.promise.then(c => { throw c; })
  ]);
}

...But that's gross.

This is better:

async function cancelMe(cancelToken) {
  await.cancelToken = cancelToken;
  doSyncThing();
  await doAsyncUncancelableThing();
  await anotherOne();
}

Defines a new meta property:

await.cancelToken

MM: Which awaits does that change?

DD: The ones afterward?

DP: How do you get rid of it in that execution?

DD: Set to null

SP: An await inside an arrow function?

  • Carry over?

DD: Syntax error

DT: Do uncancellable thing might be multi-turn, the only reason for race is you might want to do the stuff after to as a result of cancellation (I need that double checked, I don't think I got it correctly)

(We're looking at...)

async function cancelMe(cancelToken) {
  doSyncThing();
  await Promise.race([
    doAsyncUncancelableThing(),
    cancelToken.promise.then(c => { throw c; })
  ]);
  await Promise.race([
    anotherOne(),
    cancelToken.promise.then(c => { throw c; })
  ]);
}

DT: Moves final behavior from the end, to middle

DD:

DT: The conse. not obvious, not possible to test, is the "re-ordering"

DD: Not reordering

DT: it's fundamental reordering. You're moving something that is syntactically ordered, to execute out of order

YK: When async thing, await means "some promise". await.cancelToken is a new promise.

EFT: (confirm)

YK: Arrow functions do not inherit await.cancelToken because they do not generally inherit control-flow (like return) and async/await is control-flow

...

SP: There is a potential memory leak to discuss.

DD: CAn we defer that?

SP: Yes.

(discussion, re: es-discuss request for changes to this proposal)

SP: Scope of cancel? Race and All

DD: coming...

(next)

With the proposal as it is:

function delay(ms, cancelToken) {
  return new Promise((resolve, reject, cancel) => {
    const id = setTimeout(resolve, ms);

    if (!cancelToken) return;
    cancelToken.promise.then(cancelation => {
      cancel(cancelation);
      clearTimeout(id);
    });
  });
}

JHD: Would have to pass cancelation through that cancel function?

DD: Yes

Similar for XHR...

function xhrAdapted(url, { cancelToken } = {}) {
  return new Promise((resolve, reject, cancel) => {
    const xhr = new XMLHttpRequest();
    xhr.addEventListener("load", () => resolve(xhr.responseText));
    xhr.addEventListener("error", () => reject(new Error("could not XHR")));

    if (!cancelToken) return;
    cancelToken.promise.then(cancelation => {
      cancel(cancelation);
      xhr.abort();
    });
  });
}

DD: Note using new Promise which really only used when your doing async that doesn't use promises

New API:

function delay(ms, cancelToken) {
  return Promise.cancelable(cancelToken, resolve => {
    const id = setTimeout(resolve, ms);

    return () => clearTimeout(id);
  });
}

SP: want to make async function cancelable...?

DD: Still use promise constr with legacy code that doesn't use promises

DT: question about [token].promise.then...?

DD: Come back to it.

Cancel Token Composition?

Precedent from .NET:

const { token, cancel } = CancelToken.linked([ct1, ct2, …]); Here token is canceled if any of the following is true: cancel() is called ct1 becomes canceled ct2 becomes canceled … I haven’t really investigated what this is used for in the .NET ecosystem…

The extra cancel() seems useless and an artifact of the .NET setup, so instead:

.NET’s version but a little better

const token = CancelToken.some([ct1, ct2, …]); Here token is canceled if any of the following is true: ct1 becomes canceled ct2 becomes canceled ... Still unsure what the exact use cases are, but it seems plausible.

DD: Call it "some" or "any"

SP: The leak: scenario where cancel token is much longer lived thatn the code being canceled.

DD: You have one cancel token with long lifetime and components with shorter lifetime

YK: In Ember's cases, you rapidly get into situations where the cancellation is complicated to thread, e.g., async methods.

DT: You end up creating links at different points in lifecycles

DD: So there are good use cases, for CancelToken.some.

Strike: "Still unsure what the exact use cases are, but it seems plausible."

DD: So does anyone need CancelToken.every? .NET doesn't have it.

DT: Never needed it [in Midori]

YK: We should think about it because it's symmetric

DT: It's asymmetric; cancellation is monotonoic. We just don't get this pattern in Midori.

SP: Doesn't sound useful

DT: You might end up with some nice usages of 'some', so it is a good thing to have.

RW: Why not call it CancelToken.all?

DD: I should think about that harder; there was some argument about all rather than every. Anyway, this is more about 'some' given that 'every' is not useful.

RW: In favor of 'all': For explanation purposes, it would be nice to have this analogy. Apply what you already know.

YK: I have become comfortable with a cancel token as a parameter.

DD: The concern Yehuda has raised is, the semantic burden on developers of threading the cancel tokens through all the APIs, and changing all the signatures, is an issue. Should we mostly do options objects or bare parameters?

YK: Seems difficult to have a universal convention

DD: In .NET you have static types and overloads so it's easier.

DD: YK's idea was to introduce syntax for allowing cancelTokens and awaits to work better together:

async function cancelMe(cancelToken) {
  doSyncThing();
  await doAsyncUncancelableThing(cancelToken);
  await anotherOne(cancelToken);
}

To...


async function cancelMe() {
  doSyncThing();
  await doAsyncUncancelableThing(await.cancelToken);
  await anotherOne(await.cancelToken);
}

YK: This would continue with our tradition of implicit parameters, e.g. implicitly passing 'this'. You don't want to have to add it explicitly

YK:

async function cancelMe() {
  doSyncThing();
  await doAsyncUncancelableThing(await.cancelToken);
  await anotherOne(await.cancelToken);
}

let [cancelToken, promise] = [some ambiguous token] fetch(...);

MM: What would this correspond to with explicit characterization?

function fetch() {
  return await.cancelToken;
}

YK: There is a pervasive threading problem. This is analogous to new.target.

YK: [some ambiguous token] is the machinery that represents the longhand that Domenic showed


let token = new CancelToken(function(c) {

});

function fetch(

@Yehuda, can you fill in this example with some code that illustrates
whatever you were going to write,

DD: What I'm hearing is that people are not heavily concerned. Sounds like this might be worth pursuing. Cancellation already has a lot of stuff in it, and it's hard to get a read on how many people are going to have objections. Dean already raised several objections and we didn't have time in the timebox to raise all of them.

DT: good effort and really want something along the lines

YK: If the implicit argument fails, I'm not sure whether I'll be OK with this whole proposal.

DD: There is some enthusiasm for this proposal, it seems, including some of the additions. More is available in the repo. I'll add more spec'd things, including await.cancelToken, Promise.cancellable, and CancelToken.any

BT: What do cancellable promises change about async functions? Seems purely additive.

DD: Yes, seems purely additive. We don't have third state.

YK: It'd be possible for await to send cancellation tokens, but only if you do extra things to thread things through.

BT: Another question about Domenic's proposal: Is the rationale for why third state is bad documented?

DD: I'll write it up.

BT: I think it needs to be reflected, so we know years from now why we didn't go with third state.

Conclusion/Resolution

  • Continued development based on today's discussion
  • await.cancelToken
  • Promise.cancelable(...)
  • CancelToken.any|some (whichever?)
  • DT to provide direct feedback
  • DD to write up reasons why not going with third state: gist.github.com/domenic/f3ecf2dd1b27409567ba59e3fabbc047 documents the reasons briefly, as well as arguments against those reasons which were not found compelling enough to re-gain consensus on it.
  • Next meeting, I'd like to move to Stage 2

10.iv Async functions

Brian Terlson

tc39.github.io/ecmascript-asyncawait

BT: When we got async functions to Stage 3, we did spend hours talking about possible futures for cancellation and how those futures would impact async functions. We found that additive things to async functions would also be additive things to Promises. So whatever you would add to one that would be a breaking change would be a breaking change for the other. I didn't see anything in Domenic's preentation that made me think otherwise. Even the third state proposal, I'm not sure would run afowl of that.

YK: The only issue is that, in the syntactic form there's a try/catch/finally, and in the method form there isn't

AK: There is also a conern about using try and catch, without finally

YK: And it's just worse in Promises anyway

MM: The only one that makes me nervous about a possible cross-cutting concern is getting a syntax for passing the cancel token. That's the one most likely to be one where we might end up regretting simply accepting async functions as is, without also having it be a lifting mechanism for threading the cancel token.

YK: I feel pretty confident that the kind of syntaxes that we would want to use would be the same syntax for regular functions. We need the same mechanism to work within functions that aren't async functions anyway, as they need to have the parallel calling convention.

MM: of the things we heard in the previous conversation. the only cross coupling concern is the issue that YK brought up is trying ot get some useful syntact for threading the cancelToken.

MM: I don't think we should implicitly pass a parameter to existing sync function calls and change the semantics retroactively. Anyway, given the overall situation, I'm not arguing that we should hold async functions back.

WH: The grammar is both impressive and really scary, trying to see how much it can dance on the edge of a cliff without falling over — cover grammars inside of cover grammars — but I haven't found any flaws yet.

When is "await" usable as an identifier?

DE: anytime you are not in an async function. <then more details> We

implemented it all in V8

BT: It's just like yield

WH: await is different from yield in that it appears at a much higher precedence than yield.

YK: What are you worried about?

WH: Ambiguities on code sequences that start with await/ and then get interpreted in diverging ways (due to the await-as-identifier vs await-as-operator distinction that flips the / between division and starting a regexp) by cover grammars vs. real grammars. It's a potential bug farm.

WH: I am not opposed to Stage 4, just noting the potential danger.

BE: is there a way to look at the grammar of "yield" to have it work?

Conclusion/Resolution

  • Stage 4

9.iii.c Decorators

Yehuda Katz and Brian Terlson

tc39.github.io/proposal-decorators

YK: Has been working closely with Dan since the last meeting to come up with how to move forward. I want to address the technical issues. The spec is now in a Stage 2 complete state. Many have asked, why can't this be a transpiler feature. I think it's possible in principle for that to be true, but it's not as cut and dry. One problem is that it absorbs a bunch of syntax from the class body; it's important to coordinate that somewhere. You'd imagine that private state could use the @ sign, and you would want to understand that this is reserved for decorators. Also, it would be difficult to have a conversation in this committee about the class evaluation order (as last time) and interaction with features like private state. We have a lot of cross-cutting concerns to think through. The concerns from implementors is that adding more syntax features slows down the parser, which affects startup time.

MM: I was surprised by the idea of just doing this in the transpiler world.

YK: This will be standardized somehow; there are already two implementations. We should have a document that defines it, with some sort of spec. So it would have to be a delta on top of the JavaScript spec, if we keep it in transpiler land.

AWB: if it's done as a preprocessor, you'd have to do it to standard JavaScript semantics. So everything would have to be expressible in terms of the core syntax/semantics. So if the core isn't sufficient, it won't be possible to do it correctly.

YK: In order to get the semantics for high fidelity, the preprocessor will have to target ES5.

AWB: But then you can't get classes completely correct. If you were going to go the route of a preprocessor, what changes would you have to make to the current spec?

YK: We've been doing some refactoring. But it'll be hard to target ES6

MM: The decorator proposal allows a decorated constructor to result in a wrapping of the constructor. But since it's only recognized as a constructor in ES6 if it's written as a constructor, there's no way to translate

BT: In practice, you have to target functions, not classes. We will have responsibility for the problem no matter how we decide to layer it.

MM: Creating high-fidelity transpilation options on the way is a perfectly fine sequence of activity.

YK: And we will give this spec to the current transpilers. The only question is whether it's done here, or actually my opinion is that it would be somewhat possible to do as a layering

AWB: I don't think it's possible

YK: Anyone opposed to this spec being eventually in the language?

DE: I'm not convinced this spec should be in the language. Looking at Angular use cases, this doesn't support annotating parameters and other things, and there is no clear migration path to supporting those from this proposal.

DE: There is a competing feature from Angular for annotations

(There is no spec, but it's documented)

YK: I object to Angular approach, there are very real issues with that proposal that are unexplainable

JHD: The things they want don't block the addition of this feature? Why not add the other kinds of decorators later?

DE: Hard for me to see how imperative decorators like in this proposal would map to declarative ones that annotate parameters.

BE: Not here to future proof against all possible proposals by champions not in the room

YK: There is a spec here, this has years of development.

BE: too far to block

YK: Are you saying these use cases are insufficient

WH: Concerns about missing capabilities. Want to see a consistent path to annotating properties.

YK: This has become maximally minimal

DE: Concerns Andreas has raised: the decorator can run and do all kinds of things, which prevents optimizations

JHD: This is no different than the inelegant solution of O.dP after the class is defined.

BE: The question is: are we saying that we never want to do this?

EFT: Surprised that this feature is being shied from when it's beloved and widely used in other languages.

WH: I like decorators! I just want to make sure that we create a consistent design of decorators for various kinds of entities and needs rather than falling into a max-min tarpit that supports some but then precludes others due to poor design choices.

YK: Willing to champion additions to this proposal to satisfy outstanding needs.

  • The interop issue (with "annotations") has existed for some time, we can keep coming back with new features
  • The work can be done in Stage 2
  • Babel is skeptical now
  • Stage 2 signals to community

AWB: My understanding is that Stage 2 is "not locked down", the language wants to solve this problem and will eventually include the feature.

Massive agreement.

BE: Are we in favor of adding a decorators thing?

DE: Not convinced an imperative decorator is the way to go

YK: Agree to explore decorators in other positions before Stage 3

WH: Concerns about missing capabilties. Want to see a consistent path to annotating properties.

BE: (@Dan) Worry about dynamic meta programming in class declarations?

DE: (some kind of agreement)

BE: Would love static decorators, but it's a hard problem and

YK: The Annotations feature requires evaluation of expressions, is not itself static

(discussion re: static decorators)

YK: Is the concern that adding this encourages too much dynamism in class declaration code?

SM: Will existance slow it down?

  • Believes optimizations can be made to mitigate

YK: The decorator returns a descriptor that can be used, but cannot have effects on the object itself.

BT: Want to push for Stage 2

WH: If we approve this, are you committing to explore property and parameter annotations?

YK: Yes, I will do that before stage 3.

BT: Fair to make that separate?

NO.

Conclusion/Resolution

  • Stage 2 Approval

9.iii.b Private State

Daniel Ehrenberg

tc39/proposal-private-fields

Slides: docs.google.com/presentation/d/1RM_DEWAYh8PmJRt02IunIRaUNjlwprXF3yPW6NltuMA/edit

DE: I've taken on Private State proposal from Kevin Smith

AWB: Get WeakMaps out of the proposal! I don't want to see them anywhere near this proposal, whether in implementation or spec language.

  • Remove the layering violation

WH: Don't want proposal formalized in terms of weak maps either because of gc correctness concerns.

See slides

DE: Should this be "actually private"?

WH: Yes

AWB: Yes

DE: Or Reflective?

No.

See "Why inaccessible private state?" slide

"Soft Private" already available through explicit Symbol use

AWB: Big issue: we changed class instantiation to predictable shapes at the request of google. This completely throws that away

DE: We addressed that two meetings ago.

MM: The shape is static enough for the fast path to be fast. The only things that cause it not to have the shape that you expect are bizarre, rare things such as a return override or prototype mutations. Engines can still optimize for the fast path.

DE: two things we want to optimize for. 1) at the allocation site, how large (allocation size). 2) map transitions between different object states.

AWB: that's plausible; i'll need to think through it and reserve the right to bring it up again.

YK: I realize a lot of people disagree with me wanting soft-private, but we actually have to discuss it.

BT: could you expose a lower-level capability without syntax for now? (ie with computed properties + private symbols)

MM: private symbols don't work

YK: proposal would be a private object that looks a lot like a WeakMap

DE: one option is as YK said; another option would be trying private symbols, and we could work through the issue with them.

MM: if you reify private symbols, you break membranes.

MM: We're rehashing arguments we had years ago like "should private be soft or hard". There are notes.

YK: i object to the precedent "we had a binding conversation 5 years ago"

Call for Stage 2?

Conclusion/Resolution

  • We don't have enough time?