Sept 18 TC39 Meeting Notes

# Rick Waldron (12 years ago)

September 18 2012 Meeting Notes

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

Introductions. Brief Agenda tweaks

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

NL: Internationalization specs are available on the Wiki

AWB: Start with Internationalization

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

JN: Would like Internationalization tests to be included with test262

AWB: Finalize by June

Internationalization

(Presented by Norbert Lindenberg, Mozilla)

Slides

Review and Approve Final Draft of Internationalization API Specification

(Introduction)

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

Primary change is to Require Normalization By Default

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

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

YK: Because we have no evidence to the contrary

LH: That implies a judgement about design...

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

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

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

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

NL: Three options to support or ignore:

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

Don't Use Year 0 in Date/Time Formatting

2 AD, 1 AD, 1 BC, 2 BC

Discussion and explanation

YK: Ruby has a year 0

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

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

Conformance Tests

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

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

Implementor's Report

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

AWB: What is the feedback?

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

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

NC: Will be removing the prefix

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

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

RW: Is there any communication between implementors?

NC/LH: Only via es-discuss

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

Approvals

NL: Final change, move to year 0.

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

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

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

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

LH: This can be produced off-line

AWB: In the form of an Annex

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

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

Annex

Optional

All Functionality

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

Collation

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

NumberFormat

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

DateTimeFormat

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

BE: Similar to the underspecified portions of Date

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

Approval of Intl

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

…No objection.

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

JN: Any desire for ISO fast tracking?

(Discussion re: ISO benefits.)

Conclusion/Resolution ECMA-402 Approved for submission to ECMA CC & GA

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

Intl 2nd Edition

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

JN: Agenda item for Nov.

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

Conclusion/Resolution Agenda item for November 2012 to entertain a proposal.

Parallel JavaScript

(Presented by Rick Hudson, Intel)

River Trail (Intel)

Slides

Map

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

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

YK: Gratuitous API changes should be avoid

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

DH: Absolutely not the case and is very important.

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

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

LH:

Examples of Map

    paArray.map(function(element) {
      return element+1;
    });

    paArray.map(2, function(element) {
      return element+1;
    });

    paArray.map(2, function(element, [i, j], array) {
      return element+1;
    });

??

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

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

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

LH: Which means an engine cannot detect… (lost)

RH: We do rely on the programmer to know that they need to write an associative and commutative function. Tools can be provided to help.

LH: Worried about implicitly saying that a function does not match what ECMA 262 says it will mean.

DH: (Clarifies that it's just JavaScript)

BE: Parallelization can be painfully slow

YK: If it's straight forward, then why not specify how Parallelization is accomplished

DH/BE: Too early to attempt to specify Parallelization detection.

Lengthy discussion of Parallelization "mode" switching semantics… Devolved. Ended abruptly when no progress was made.

Shape

  • Mixing 1D and 2D operations requires an understanding of shape
  • Shape determined at construction

Identity

  • Accessors to non leaf elements of ParallelArrays will return a fresh ParallelArray
  • References semantics for === remains consistent

Between the two:

  • pa[2] === pa[2] true for only 1D ParallelArrays
  • pa[2] === pa[2] always false when shape is > 1

LH: Asks for explanation…

DH: Will fill in blanks offline

AWB: Are there any other efforts that are developing competing specifications?

RH: Not exactly, but WebCL(Kronos?) is similar in the application they are trying to address.

DH: A different name?

BE: Vector?

DH: Also, the world will hate us for creating a new Array-like.

RW: Only a problem when creating constructors that produce objects with numeric indices and a length property and no Array proto API.

DH: Which it does.

RW: Then it will be a problem.

MM: The proliferation of Array-like things is unfortunate

RW: And ES6 reduces that pain by effectively eliminating arguments via rest and Array.from()

DH: There was also the idea of having parallel-specific methods.

Derailed to Array-like API issues on the whole… When to implement array API and when not. Why and why not…

Conclusion/Resolution Further research and offline discussion.

Define Properties Operator ":="

(Presented by Allen Wirfs-Brock, Mozilla)

Introduction, rationale as published:

strawman:define_properties_operator

DH/AWB/RW: (discussion) Object.define, Object.put

RW: Have research and supporting cases from jQuery, Dojo, YUI, Node core, Underscore… Always exists an approximation of "merging" or "extending"

AWB: We should strive to fix the future and correct developers thinking about "define" and "assign"

LH: That's a dangerous scenario to put developers in, where they have to think about assignment vs definition.

RW: The newly created dom node case, for batch property assignment (originally brought forth by Doug) is the second most important use-case, but implicit define will pave innerHTML (or any dom node properties)

DH: Shouldn't create syntax for the less common operation.

MM: Agreed.

AWB: But there is no way to:

  • Batch define class-side properties
  • Batch define constructor properties
  • Batch define instance properties

YK: Nothing for static properties in classes yet anyway

MM: But not sure we need any syntax yet. If there was a lot of precedent for batch define, in the same way there is for assign/put, then it would make sense, but there is very little userland history for define

RW: Agreed, assign/put is a cow-highway to pave, but user code has barely begun to include regular use of definePropert(y|ies)

MM: (comments about private name access concerns)

AWB:

LH: Long term, we're going to have to consider features that are allowed to move private state.

DH: Essentially, you'd need inside access and list private items.

Discussion about side channel access via newly defined properties that were never expected on the object.

Discussion about the needs of Private Names, Unique Names and WeakMaps.

BE: People want Private Names as much as they want Unique Names

YK: Can we tell people to use Unique Name when they want copyable and Private Name when not.

BE: I thought of this earlier, but wasn't sure, but it could work

AWB: …

MM: Given ES6, remove the copying of private names, allow copying unique names: Can this be written as library code?

DH/YK/RW: Devs want Object.define which is Object.defineProperties Object.assign() or Object.put() (these are the same, just different names)

Extensive discussion around whether or not Object.define()

Extensive discussion around whether or not Object.assign()

Derailed due to concise method's making non-enumerables, which means they won't copy if the rule disallows copying.

…Revisit "Concise Method Definition" (add anchor)

Object.define( target, source )

  • All own properties of source
  • plain object descriptor map is copied
  • private names are not copied
  • unique names are copied
  • super mechanism (rebind super)

Object.assign( target, source )

  • Only enumerable own properties of source
  • Invoke [[Get]] on property list derived from source, for each property in list [[Put]] on target
  • private names are not copied
  • unique names are copied
  • super mechanism (rebind super)… AWB To determine needs
  • Returns modified "target"

DH, MM, AWB: Object.assign a well worn enough cow-path to be worth paving. Object.define isn't, and so should only be standardized after libraries have explored the space.

Conclusion/Resolution

Accept Object.assign into ES6, but postpone Object.define (or something like it) to discussion of future versions.

Reference materials and use cases: gist.github.com/3744794

(** The inclusion of variable length sources is imperative to match real world patterns found in the most ubiquitous JS libraries)

Concise Method Definition, Revisited

RW: Defaulting concise methods to non-enumerable is a mistake

DH: Not sure about the decision to go non-enumerable. Users expect that things they create to be enumerable and things that the platform provides to be non-enumerable.

LH: enumerability is not a real concept with any sort of meaning.

EA: (reveals the broken-ness of the DOM)

No longer arguable.

Conclusion/Resolution Concise method definitions create [[Enumerable]]: true

Scoping of the Top Level

var and the window.prototype issue

var indexedDB = window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.indexedDB;

Issue with WebIDL change.

REVISIT.

let, const, module, class

Global scope contours

AWB: propose extra global contour, shared across all scripts, for new binding forms, to avoid colliding with Window object

others skeptical of complexity of new scoping model for globals

Conclusion/Resolution

continued on second day, resolved then

# Rick Waldron (12 years ago)

September 19 2012 Meeting Notes

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

Recap of Sept 18th notes.

Proxy

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

Enumerate Traps Return Types

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

Conclusion/Resolution

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

Revokable Proxies

TVC: The Problem

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

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

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

Proposed Solution

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

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

Proposal:

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

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

…Bikeshedding the spelling of "Revokable"

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

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

RW/DH: Agree this is an issue.

MM: static on the Proxy object?

Yes.

… Discussion about the naming.

Proposal: Proxy.revocable

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

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

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

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

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

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

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

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

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

DH:

RWS: Does this problem exist…

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

WH: Direct proxy, not allowed to muck with

MM: Are

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

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

WH: I'm not sure about it

DH: He jsut gave proof.

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

WH: Are there other traps affected by this?

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

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

MM: No

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

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

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

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

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

MM: Specify that…

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

WH: An uneasy feeling about what else is hiding

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

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

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

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

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

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

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

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

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

WH: Again, still not sure about effects throughout proxy

MM/AR: (discussion about frozen object stability)

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

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

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

Conclusion/Resolution

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

Proxy and Private Names

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

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

Later determined that this would become cumbersome.

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

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

WH: What makes them non-forgeable

STH: They are objects

DH: And are as non-forgeable as objects,

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

AWB: They are both useful

STH: Unique names give you actual unforgeability

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

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

MM: Should probably use a WeakMap…

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

STH: Erik is right, but it a

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

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

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

DH: Should champions take this offline?

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

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

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

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

STH/LH/RW: Will need to spec WeakSet

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

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

WeakSet

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

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

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

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

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

Syntactic Support for Private Names

(Presented by Allen Wirfs-Brock, Mozilla)

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

Private Names & @Names

Unique/Private Names

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

  • Currently no syntactic support for definition of use

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

eg.

    const secret = Name();
    let o = { secret: 42 }; // does not define a "Name" prop

    class MyClass extends Yours {
            secret() {
                    this.mine();
                    super[secret]();
            }
    }

    // Not allowed:
    MyClass.prototype[secret] = function() {
            super[secret]();
    };
    //... Because super is banned outside of class

Computed Property Names for Object Literals Were Abandoned…

    const secret = 42;
    let o = { [secret]: 42 };

    class MyClass extends Yours {
            [secret]() {
                    this.mine();
                    super[secret]();
            }
    }

Issues:

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

Proposal At-Names

Slides

  • An At-Names is an IdentifierName that is lexically prefixed with @

  • At-Names are const bound to Name values by new declaration forms

      name @x, @y;
      priv @secret;
    
  • Such declarations implicitly create Name Objects

… Missed slides

At-Name References

  • At-Name can appear in any context where an IdentifierName would be interpreted as a literal property name.

    • As a prop name in object literals/class defs
    • After . in MemberExpressions
  • Lexical scoping rules resolve such At-Name references to a Name object value.

      private secret;
      let o = { @secret: 42 };
    
      class MyClass extends Yours {
              @secret() {
                      this.mine();
              }
      }
    

At-Names in Primary Expressions

  • When used as Primary expression, an At-Name… (see slides)

      obj. at secret
      obj[@secret]
    

    // same thing

Name Declarations with Initializers

  • In a name/private declaration, each At-Name may have an initialization expression.

      private @secret = NameBroker.provideName(secretcode);
    
  • The initializer must evaluate to a name object

  • Primary use case is initializing an At-Name to a name provided via a function call or other computed value (the provided name or computed value is "secretcode").

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

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

    foo @IdentifierName

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

DH: You've won me over

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

MM/AWB/YK: (discussion about simplification)

DH: (whiteboard)

    let o =        {
            private @foo: 42,
            m() {
                    return this. at foo;
            }
    }

    o.m(); // 42

    // As seen via inspection (REPL, console)

{ m() {} }

…Discussion about varying semantics lacking in previous proposals.

MM: Cannot avoid runtime collision?

DH: We can

MM: Should throw?

DH: Not strictly, but a possibility.

AWB: function vs. cost

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

Optional Feature: Class-scoped name declarations

  • Allow name/private declarations to occur as a class body element

  • Any such declared At-Name are scoped to the class body.

      class Point {
              private @x, @y; // <=== scoped to class body
              constructor(x, y) {
                      this. at x = x;
                      this. at y = y;
              }
              get x() { return this. at x; }
              get y() { return this. at y; }
      }
    

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

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

RW: Fully support this.

LH: Let's work towards understanding the entire commitment

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

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

WH: classes are not worth it without this

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

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

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

DH: (rebuked)

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

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

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

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

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

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

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

RW: (agrees)

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

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

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

BE: Firm disagreement.

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

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

LH: I want something more minimal.

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

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

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

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

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

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

AWB/WH/BE: Yes, I agree.

DH/BE: Move protected to a new strawman.

Conclusion/Resolution Consensus on:

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

Deferred to separate proposal:

  • "Protected"

Renaming Name to Symbol

(Presented by Dave Herman, Mozilla)

YK: A little nervous that not identical to Lisp

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

symbol, whereas in lisp you can

YK: ok with that.

Conclusion/Resolution

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

Early Errors That Possibly Should Not Be

(Presented by Luke Hoban, Microsoft)

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

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

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

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

[Debate, without resolution]

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

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

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

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

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

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

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

[Macros require compile time expansion]

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

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

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

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

DH/BE: Continue research of macros, offline.

MM: List all early errors and discuss the merits

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

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

Discussion of label analysis

Strict mode implementation

Conclusion/Resolution

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

Performance Costs of Temporal Dead Zone

(Presented by Luke Hoban, Microsoft)

esdiscuss/2012-September/024993

LH: (introduces discussion)

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

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

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

…Will continue with testing and gather evidence.

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

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

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

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

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

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

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

Conclusion/Resolution

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

Global Scope Revisit

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

BE: Recap the problem that revealed the issue.

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

Current proposal… let would shadow var

ARB: Why?

BE: Global contour in which let binds

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

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

LH:

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

BE: It happens all the time…

    for (var i = 0; …) {}

    for (var i = 0; …) {}

…Not the issue, but this:

    var i;
    for (i = 0; …) {}

    var i;
    for (i = 0; …) {}

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

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

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

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

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

BE:

    A <script>
    B <script> document.write("D <script>")
    C <script>

( G ) < ^ ( D ) ( A ) ^ ( B ) <-? ^ ( C ) <-?

Hell.

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

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

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

LH: It has to be.

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

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

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

YK: (whiteboard)

    <script>
            function animate() {
              requestAnimationFrame();
            }
    </script>
    <script>
            let requestAnimationFrame;
            if ( typeof requestAnimationFrame === "undefined" ) {
                    requestAnimationFrame = …polyfill.
            }
            animate();
    </script>

BE: Recapping the Window.prototype issue

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

…More discussion…

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

…Discussion…

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

ARB:

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

…Discussion about the

Two models to consider:

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

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

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

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

DH: no difference

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

DH: I still don't see the difference

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

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

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

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

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

BE/DH/ARB…

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

Unless there is a lexical scope or hidden data store…

LH: Observability?

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

LH (recapping one of the alternative models)

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

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

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

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

Test 262

(Presented by Istvan Sebastian, ECMA)

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

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

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

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

Create Archival Utility for ECMA Wiki

Conclusion/Resolution Rick Waldron will champion this

# Rick Waldron (12 years ago)

September 20 2012 Meeting Notes

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

Object.observe Update

(Presented by Rafael Weinstein, Google)

REQUEST SLIDES!

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

Updates to strawman:

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

ChangeSummary.js (experimental library) rafaelw/ChangeSummary

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

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

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

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

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

RWS: Sounds like there are specific issues?

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

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

AWB: Yes, sufficient.

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

RWS: (presenting demo)

ADD LINK

Discussion about "read" notifications and performance concerns.

YK: Willing to move Ember, despite the scale

EF: Did Angular replace all dirty checking?

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

Observing Computed Properties and Dependencies

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

Tuning Spec, Implementation Complexity

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

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

Synchronous Delivery?

NO.

Security Mitigations

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

WH: What happens when the argument is a Proxy?

RWS: Returns the Proxy's notifier

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

ARB: Not sure if this is true.

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

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

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

Creator of an object:

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

This is an intended mechanism of the Proxy proposal

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

oldValue

Most use cases would create copy of all observed data

WH: What about accessors?

RWS: accessors don't notify

WH: That's bad.

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

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

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

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

YK: (Supported use story in Ember)

…Mixed discussion about far future notifier patterns:

    // no-op, just for example...
    function handler( changeRecord ) {
      console.log( changeRecord );
    }

    class Foo {
      private @x, @notifier;

      constructor(x) {
        this. at x = x;

        Object.observe(this, handler);

        this. at notifier = Object.getNotifier(this);
      }

      get x() {
        return this. at x;
      }

      set x(v) {
        this. at notifier.notify({
          object: this,
          name: "x",
          type: "updated",
          oldValue: this. at x
        });

        this. at x = v;
      }
    }

    var f = new Foo("hello");
    f.x = "Hola";

    // synthetic change event fired with "changeRecord"
    // defined in the set x() accessor

Discussion regarding the feasibility of adding to ES6.

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

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

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

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

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

Officially Promoted to proposal for ES7.

Grammar Validation

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

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

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

Resolution on the yield issue?

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

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

BE/AWB: Who is going to own this?

Conclusion/Resolution Waldemar is going to try to work on this

Formal Parameter Scope

(Presented by Brendan Eich, Mozilla)

With regard to default formal parameters…

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

    var b = "outer";
    function f(a = x, b = a * b, c = c * g() ) {
            /*
            three scopes:
                    (a),
                    (a and b)
  (a, b, c)
            */
    }

Realistically, it should desugar, scope rules included:

    var b = "outer";
    function f(a, b, c) {
            if ( a === void 0 ) a = x;
            if ( b === void 0 ) b = a * b;
            if ( c === void 0 ) c = c * ();

            function g() {} // will hoist
    }

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

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

With let x this is an error:

    function f( a = "a" ) {
            let a;
      var a;
    }

Not let bindings

    f(a = b, b = 3)

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

ARB: (whiteboard)

    function f(x = (y = 42), y = 41){}

    f();

    42, 42

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

Remind why only "no read before write"?

BE: 2 years ago in redmond agreement.

AWB: (explains the rationale and current semantics)

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

MM: let guards were the original reasoning.

DH: let guards should be different from just let

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

STH: Need to provide an argument beyond that

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

DH: This is far future, hypothetical

MM/DH: related to temporal dead zone discussion.

LH: The temporal dead zone opposition is perf

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

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

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

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

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

DH: (missed not about read barrier)

WH:

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

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

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

AWB: Ok to revisit for valid reasons…

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

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

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

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

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

Array.of Rename?

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

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

Array.of()

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

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

Conclusion/Resolution No change, no revisit.

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

Thin Arrow?

(Presented by Brendan Eich, Mozilla)

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

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

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

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

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

Conclusion/Resolution Consensus holds on fat-arrow

Existential Operator (strawman discussion)

(Presented by Brendan Eich, Mozilla)

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

    o = {}
    r = o?.p.q.r
    r = o?.p?.q.r

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

ARB: This is non-compositional

    o = {}
    r = o?.p.q.r
    r = (o?.p).q.r
    r = o?.p.q.r()

Results in…

    var o, r;
    o = {};
    r = o != null ? o.p.q.r : void 0;
    r = (o != null ? o.p : void 0).q.r;
    r = o != null ? o.p.q.r() : void 0;

Non-starter.

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

    o?.p?.q?.r

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

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

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

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

General agreement.

Conclusion/Resolution Seems useful, but not now. Semantics are unclear

Generators

thisBinding

Generator thisBinding is the thisBinding of the original generator call.

    class MyArray extends Array {
            *iterator() {
                    let last = this.length;
                    let next = 0;
                    while (next < last) yield this[next++];
            }
    }

Generator object API?

    class MyArray extends Array {
            *iterator() {
                    let last = this.length;
                    let next = 0;
                    while (next < last) yield this[next++];
            }
    }

    new MyArray(4, 8, 15, 16, 23, 42).iterator();

…returns a generator instance that will have generator methods

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

DH: Agrees

LH: Specify the generator?

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

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

MM: what is the minimal method interface?

DH: send, throw, close

Discussion around specifying a generator contract.

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

AWB: Need something for spec

YK: If everyone implemented iterators with generators

DH: Not super worried about this…

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

Notably: Significant dissent on throwing exceptions for control flow.

Continued discussion of note…

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

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

LH: (whiteboard, example misuse of iterator)

BE: Historically, not an issue.

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

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

Discussion about protocol specifications, where precedent exists.

Supplemental tests for Tests 262

SpiderMonkey and v8 are writing tests, can contribute back.

Need parity, it's hard.

Goals

AWB: January, spec: feature complete.

LH: Multiple implementations?

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

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

# Brendan Eich (12 years ago)

Rick Waldron wrote:

Global Scope Revisit

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

BE: Recap the problem that revealed the issue.

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

Current proposal… let would shadow var

ARB: Why?

BE: Global contour in which let binds

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

Last line should be "var and let of the same name", not "var and function ...."

# Brendan Eich (12 years ago)

Rick Waldron wrote:

Thin Arrow?

(Presented by Brendan Eich, Mozilla)

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

"bound 'this'" would do -- "hard-bound" if you insist.

I think soft-bind is dead as discussed here, since it adds a flag argument or equivalent that must be set by every caller anywhere -- this won't fly with V8 and SpiderMonkey and other engines.

I'd prefer just "bound" so we can stop pretending there's a "soft" option.

# Rick Waldron (12 years ago)

On Thu, Sep 27, 2012 at 11:54 PM, Brendan Eich <brendan at mozilla.org> wrote:

Rick Waldron wrote:

Thin Arrow?

(Presented by Brendan Eich, Mozilla)

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

"bound 'this'" would do -- "hard-bound" if you insist.

I think soft-bind is dead as discussed here, since it adds a flag argument or equivalent that must be set by every caller anywhere -- this won't fly with V8 and SpiderMonkey and other engines.

I'd prefer just "bound" so we can stop pretending there's a "soft" option.

Sorry, I likely misheard you, I'll correct the notes before I submit to ECMA

# Rick Waldron (12 years ago)

On Thu, Sep 27, 2012 at 11:44 PM, Brendan Eich <brendan at mozilla.org> wrote:

Rick Waldron wrote:

Global Scope Revisit

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

BE: Recap the problem that revealed the issue.

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

Current proposal… let would shadow var

ARB: Why?

BE: Global contour in which let binds

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

Last line should be "var and let of the same name", not "var and function ...."

This will be corrected in the notes submitted to ECMA

# Brendan Eich (12 years ago)

Rick Waldron wrote:

Notably: Significant dissent on throwing exceptions for [iteration protocol termination] control flow.

Counter-argument based on Python design and experience is that by far the most uses of iterators never have to try/catch and simply use for-of (for-in in Python) constructs: loops, comprehensions, generator expressions. The StopIteration exception cannot escape such constructs and won't be an issue in real debuggers (which must always provide exception filters, including sane defaults).

BE cites years of experience with thousands of users via Python 2.5+ and JS1.7+.

BE hierarchy of user population sizes related by >> ("much greater than"):

| group 1: users of iterators via for-of, no try-catch needed, no problems |

| group 2: implementors of iterators who do not need to try-catch,

just throw StopIteration |

| group 3: implementors of task.js-like raw try/catch-StopIteration

coroutine libraries |

Some debate about ordering of group 2 vs. 3 sizes, LH cited C# different experience but BE pointed to different design evolution and final design state.

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

Disallows iterating over the in-band value. We've discussed this in the past, want true OOB StopIteration to avoid this ad-hoc and uncheckable restriction.

Discussion about protocol specifications, where precedent exists.

Rehashed Java (hasMore/getNext) and C# (Current/MoveNext) protocols involving two methods, which costs more for implementors (groups 2 and 3, however ordered) and adds incoherence hazard (two methods get out of sync; C# tries to mitigate common mistake with Java's, but still has dual out-of-sync hazard to Java's).

MM agreed with BE that Python's is simplest given other constraints we can't change, or "least bad".

Consensus holds in my view and if it didn't we couldn't hold it on a great many things. I write these notes with some trepidation since iteration protocols and exceptions for restricted control effects are always going to excite debate. But full disclosure is best. These are my missing notes for the meeting notes, which I thought got too sparse here.

# Alex Russell (12 years ago)

On Sep 28, 2012, at 7:54 AM, Brendan Eich <brendan at mozilla.org> wrote:

Rick Waldron wrote:

Thin Arrow?

(Presented by Brendan Eich, Mozilla)

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

"bound 'this'" would do -- "hard-bound" if you insist.

I think soft-bind is dead as discussed here, since it adds a flag argument or equivalent that must be set by every caller anywhere

It's demonstrably the same overhead as hard binding.

-- this won't fly with V8 and SpiderMonkey and other engines.

I'd prefer just "bound" so we can stop pretending there's a "soft" option.

-- Alex Russell slightlyoff at google.com slightlyoff at chromium.org alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

# David Bruant (12 years ago)

Thanks Rick for the notes (and everyone who contributed, I see several colors)

Le 28/09/2012 03:00, Rick Waldron a écrit :

Proxy

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

Revokable Proxies

(...)

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

I think it's possible to implement both without any overhead. TVC suggested below that a revoked proxy is equivalent to a proxy with all traps unconditionally throwing; well, a proxy, when revoke could drop its target and change its handler on revokation.

A proxy can be modelled as {target, handler}. Both handler and target are set at proxy creation and can't be changed arbitrarily by JS code. We can model revocation as a capability that enables to change in one operation both target to null and handler to a built-in handler which throws on any operation. (it remains impossible to change target and handler arbitrarily in JS code) Modeled and implemented this way, there is no need for a null check. When trapping, the revoked target (null) is passed to the handler trap, which doesn't care since it throws regardless of the target value. In that model, both type of proxies are just the same type and are as efficient. No need for a null check before trapping. Just trap with the current value and only provide to JS-land the capability to change the target (only to a null value) through revokation.

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

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

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

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

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

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

Arguably, a revoked proxy could throw on === or typeof too. It's already allowed to arbitrarily throw on [[Get]], [[Put]], 'in', for-in/of loops, Object.getPrototypeOf, etc. It's not that big of a stretch to throw on typeof or === even though these aren't trappable. Unconditionally trapping on any operation on the object is future-proof.

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

MM: No

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

I agree. If it's proven that the availability guarantee really matters in some cases, I think a lot of things need to be re-designed in the proxy API. How much does it matter?

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

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

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

I agree. Proxies are a tool a virtualization. Restricting the way proxies proxy through invariant checking is one thing, but preventing from proxying seems to be a step too far in my opinion.

(...)

Conclusion/Resolution

  • we want revocable proxies
  • further discussion is needed on revoking frozen objects, either via revocable proxies or via traps var t = Object.freeze({s: a300MbString}); var {revoke, proxy} = Proxy.revokable(t, {}); revoke(); proxy.s; // ?

If the result is the long string because t is frozen, then it defeats the purpose of why revokation is being introduced in the first place (see TVC's problem description).

Proxy and Private Names

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

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

Later determined that this would become cumbersome.

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

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

WH: What makes them non-forgeable

STH: They are objects

I think it was Tom who suggested in a post that symbols (I'll do my best to use the new terminology!) are more non-forgeable strings than non-forgeable objects. Symbols should not be proxyable. Their only important attribute is their identity, so proxying them would be absurd. I think it should be considered to have symboles typeof to be "string" instead of "object", or maybe something completely new, but for sure, they are not objects.

DH: And are as non-forgeable as objects,

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

AWB: They are both useful

STH: Unique names give you actual unforgeability

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

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

MM: Should probably use a WeakMap...

Why so? I agree on the "weak", but it seems we want the whitelist to be a set. The only operation on the whitelist internally is "has". It's useful if JS code can "add" and "remove" elements. It looks like the contract of a set, doesn't it?

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

STH: Erik is right, but it a

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

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

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

DH: Should champions take this offline?

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

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

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

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

Typof. I think you meant WeakSet.prototype.has (WeakSets have no "get").

STH/LH/RW: Will need to spec WeakSet

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

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

WeakSet

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

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

Application code can enforce that if necessary:

Object.defineProperty(this, 'WeakSet', {configurable: false,

writable: false});

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

The first code that runs in a fresh ECMAScript environment is the one in charge of deciding what can be redefined and what cannot. The first code that runs decides of the security policy. If it's a defender, it can freeze built-ins. If it's an attacker, it can redefine built-ins in harmful way. If no choice is made by the first code, the next piece of code decides and so on.

In my opinion, the structure of any secure and reliable JavaScript (ES5) application should be like:

  1. enhance environment (polyfills, libraries, etc.)
  2. freeze built-ins (via initSES.js or equivalent)
  3. application code

ES6 Modules may change this. I haven't given much thoughts of how it does.

# Rick Waldron (12 years ago)

Ugh, sorry about that. I had a momentary brain melt and forgot to unformat before sending

# Brendan Eich (12 years ago)

Alex Russell wrote:

On Sep 28, 2012, at 7:54 AM, Brendan Eich<brendan at mozilla.org> wrote:

Rick Waldron wrote:

Thin Arrow?

(Presented by Brendan Eich, Mozilla)

We have the fat-arrow, supported by Kevin Smith's research, it's a win. Some voices in the community don't want the unexpected behaviour of the soft-bound lexical this "bound 'this'" would do -- "hard-bound" if you insist.

I think soft-bind is dead as discussed here, since it adds a flag argument or equivalent that must be set by every caller anywhere

It's demonstrably the same overhead as hard binding.

Yes (and I reject your bogus jargon :-P), but that's not the point. The comparison to make is with all functions, not just bound functions.

With soft-bind, every call to any function would have an extra parameter, even if the function has dynamically bound |this|; or else target soft-bound functions would have to be dynamically recompiled/respecialized (equivalent to the extra parameter).

See esdiscuss/2012-May/023002, quoting:

  1. Implementations including beloved V8 and venerable SpiderMonkey would have to recompile target soft-bound functions, or else provide an extra parameter to replace what is for =>a lexical up-var reference. And extra

parameters and/or recompilation steps cost performance and code complexity, always.

# Tom Van Cutsem (12 years ago)

replies in-line below:

2012/9/28 David Bruant <bruant.d at gmail.com>

Thanks Rick for the notes (and everyone who contributed, I see several colors)

Le 28/09/2012 03:00, Rick Waldron a écrit :

Proxy

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

Revokable Proxies

(...)

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

I think it's possible to implement both without any overhead. TVC suggested below that a revoked proxy is equivalent to a proxy with all traps unconditionally throwing; well, a proxy, when revoke could drop its target and change its handler on revokation.

A proxy can be modelled as {target, handler}. Both handler and target are set at proxy creation and can't be changed arbitrarily by JS code. We can model revocation as a capability that enables to change in one operation both target to null and handler to a built-in handler which throws on any operation. (it remains impossible to change target and handler arbitrarily in JS code) Modeled and implemented this way, there is no need for a null check. When trapping, the revoked target (null) is passed to the handler trap, which doesn't care since it throws regardless of the target value. In that model, both type of proxies are just the same type and are as efficient. No need for a null check before trapping. Just trap with the current value and only provide to JS-land the capability to change the target (only to a null value) through revokation.

I think you're right. We might actually use this to our advantage to specify revokable proxies in a modular, non-intrusive way. That is, rather than specify revokable proxies by explicitly including a null-check in all of the algorithms for proxies, we could also specify that the revoke() function, when called, replaces its proxy's [[Handler]] with a special built-in handler that throws a TypeError on all traps. Implementors would still be free to implement it another way.

Allen, what do you think?

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

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

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

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

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

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

Arguably, a revoked proxy could throw on === or typeof too. It's already allowed to arbitrarily throw on [[Get]], [[Put]], 'in', for-in/of loops, Object.getPrototypeOf, etc. It's not that big of a stretch to throw on typeof or === even though these aren't trappable. Unconditionally trapping on any operation on the object is future-proof.

I don't think it would be a good idea to have === and typeof throw on revokable proxies. First, it breaks the simple story of "a revoked proxy is just a proxy with a handler that throws". Second, let's not forget that the reason that === and typeof aren't trapped in the first place is so proxies wouldn't influence their behavior!

For typeof it might still be reasonable, as the result of that operator really depends on some state of the proxy target, which the revoked proxy must remember separately. But '===' tests identity, which is (and remains) a property of the revoked proxy itself. This operator doesn't need the target to produce its result.

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

WH: What makes them non-forgeable

STH: They are objects

I think it was Tom who suggested in a post that symbols (I'll do my best to use the new terminology!) are more non-forgeable strings than non-forgeable objects. Symbols should not be proxyable. Their only important attribute is their identity, so proxying them would be absurd. I think it should be considered to have symboles typeof to be "string" instead of "object", or maybe something completely new, but for sure, they are not objects.

I agree that proxying a symbol is of little value, but I didn't say that symbols are closer to strings than to objects. I think symbols are closer to objects: they have an unforgeable identity. Strings don't have that, objects do.

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

Typof. I think you meant WeakSet.prototype.has (WeakSets have no "get").

Indeed. It should be "has".

Note that you made a typo in the word "Typof". A meta-typo! ;-)

# Brendan Eich (12 years ago)

David Bruant wrote:

I think it's possible to implement both without any overhead. TVC suggested below that a revoked proxy is equivalent to a proxy with all traps unconditionally throwing; well, a proxy, when revoke could drop its target and change its handler on revokation.

In the words of Basil Fawlty, BRILLIANT!

Why didn't we think of it?

# David Bruant (12 years ago)

Le 28/09/2012 17:31, Rick Waldron a écrit :

Ugh, sorry about that. I had a momentary brain melt and forgot to unformat before sending

Ahah, don't worry about it :-)

# Axel Rauschmayer (12 years ago)

Right. I think it's pretty.

-- Dr. Axel Rauschmayer rauschma.de [Sent from a mobile device, please forgive brevity and typos]

# David Bruant (12 years ago)

Le 28/09/2012 18:28, Tom Van Cutsem a écrit :

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

WH: Not sure about this as a feature, w/r to future hostility…
-  eg. if "===" would trap to the handler how does this work with
that?

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

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

BE: It remembers "function" or "object"
TVC: right
Arguably, a revoked proxy could throw on === or typeof too.
It's already allowed to arbitrarily throw on [[Get]], [[Put]],
'in', for-in/of loops, Object.getPrototypeOf, etc. It's not that
big of a stretch to throw on typeof or === even though these
aren't trappable.
Unconditionally trapping on any operation on the object is
future-proof.

I don't think it would be a good idea to have === and typeof throw on revokable proxies. First, it breaks the simple story of "a revoked proxy is just a proxy with a handler that throws". Second, let's not forget that the reason that === and typeof aren't trapped in the first place is so proxies wouldn't influence their behavior!

For typeof it might still be reasonable, as the result of that operator really depends on some state of the proxy target, which the revoked proxy must remember separately. But '===' tests identity, which is (and remains) a property of the revoked proxy itself. This operator doesn't need the target to produce its result.

This point started with an "what if typeof/=== is trappable?". If it's sure that it never becomes trappable, everything's good.

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

WH: What makes them non-forgeable

STH: They are objects
I think it was Tom who suggested in a post that symbols (I'll do
my best to use the new terminology!) are more non-forgeable
strings than non-forgeable objects. Symbols should not be
proxyable. Their only important attribute is their identity, so
proxying them would be absurd.
I think it should be considered to have symboles typeof to be
"string" instead of "object", or maybe something completely new,
but for sure, they are not objects.

I agree that proxying a symbol is of little value, but I didn't say that symbols are closer to strings than to objects.

sorry for the misquote :-s

AWB: Not clear how using a built-in WeakSet will protect, what if
it's been redefined? Are WeakSet methods non-writable?
TVC: we need to specify that the proxy calls the
original/intrinsic WeakSet.prototype.get method.
Typof. I think you meant WeakSet.prototype.has (WeakSets have no
"get").

Indeed. It should be "has".

Note that you made a typo in the word "Typof". A meta-typo! ;-) :-) "typof". My fingers are so used to "typeof"...

# Brendan Eich (12 years ago)

David Bruant wrote:

This point started with an "what if typeof/=== is trappable?". If it's sure that it never becomes trappable, everything's good.

I'm not sure everything's good -- MM at the meeting (Mark Miller ;-) said lots would change. We don't need to future-proof by inventing that future right now, so I agree with Tom. Let's leave === and typeof as is.

# David Bruant (12 years ago)

Le 28/09/2012 19:56, Brendan Eich a écrit :

David Bruant wrote:

This point started with an "what if typeof/=== is trappable?". If it's sure that it never becomes trappable, everything's good.

I meant "If it's sure that they (typeof/===) never become trappable, everything's good (in the sense that there is no need to throw on what will not be a trap)"

I'm not sure everything's good -- MM at the meeting (Mark Miller ;-) said lots would change. We don't need to future-proof by inventing that future right now, so I agree with Tom. Let's leave === and typeof as is.

Sounds good, I agree too.

# Andreas Rossberg (12 years ago)

On 28 September 2012 18:28, Tom Van Cutsem <tomvc.be at gmail.com> wrote:

I agree that proxying a symbol is of little value, but I didn't say that symbols are closer to strings than to objects. I think symbols are closer to objects: they have an unforgeable identity. Strings don't have that, objects do.

I don't follow how generative creation is synonym to "identity", nor how identity implies being an object. Should we make everything an object just because we can? For symbols in particular I completely fail to see a good reason for doing so (now that we are able to drop the "public" name property). It will just induce extra cost for dubious semantic value -- or actually, semantic cost, as the issue of proxying them indicates.

# Rick Waldron (11 years ago)

Sept 17 Meeting Notes

John Neumann (JN), Dave Herman (DH), Istvan Sebestyen (IS), Alex Russell (AR), Allen Wirfs-Brock (AWB), Erik Arvidsson (EA), Eric Ferraiuolo (EF), Doug Crockford (DC), Luke Hoban (LH), Anne van Kesteren (AVK), Brendan Eich (BE), Brian Terlson (BT), Rick Waldron (RW), Waldemar Horwat (WH), Rafael Weinstein (RWS), Boris Zbarsky (BZ), Domenic Denicola (DD), Tim Disney (TD), Niko Matsakis (NM), Jeff Morrrison (JM), Sebastian Markbage (SM), Oliver Hunt (OH), Sam Tobin-Hochstadt (STH), Dmitry Lomov (DL), Andreas Rossberg (ARB), Reid Burke (RB)

Welcome

RW: (Logistics)

Agenda

Promises to be discussed Thurs. PLH from W3C will be here on Wed/Thurs.

BE: won't be here thurs, and that suits me.

JN: objections to using this agenda?

(crickets>

JN: next issue is approving the agenda.

Approved.

JN: Minutes approval?

RW: (Confirms no changes since last review)

Approved.

JN: have a strong duty to surface the agenda to ECMA and right now we don't know how to do that. Want to publish something to ECMA 3 weeks before the meeting and one week before, a final version of the agenda.

AVK: how about we give them a URL?

IS: the issue is that we haven't had a fleshed-out agenda 3 weeks before the meeting. There hasn't been anything there.

AR: this seems like a mismatch between the historical timings of meetings and our accelerated cadence.

DH: We talked about this in last meeting, where we agreed that everything would be in the agenda one week prior. If we don't accept new items, the agenda is a dead letter.

AR: we can commit to having a skeleton that has stuff we will usually talk about, but not more.

RW: in the past, an email went out that helped remind people. If we sent out a reminder email at the halfway point, it might help people remember to add agenda items then.

DH: Let's strategize which items are best to work on and which day.

  • Modules: Wait for Andreas

  • Typed Arrays: Wait for Dmitry, Oliver

  • Symbols: wait for Andreas

  • Proxies: wait for Tom VC

DH: Arrows, Math.hypot today

EA: Spec process

DH: We can do this out of order. ...Let's discuss Data parallelism while Niko Matsakis is present.

11. Status Report 262

AWB: I'd like feedback and comments on the new re-orderings.

DH: I know that Jason Orendorff has some issues (es-discuss: esdiscuss/2013-September/033314(starting with Olliver Hunt))

AWB: New sections...

  • Runtime Abstractions
  • Group Of Chapters that define the language
  • Lexical Grammars
  • Syntactic Grammars

AWB: There was some recent discussion about how you track down semantics when you have so many named semantic algorighms that are associated with productions. I've done work subsequent to r18 that adds a "see also" section at the top of each segment so you can

BE: what do people think of the new organization?

(general approval>

WH: The latest version sent to the ECMA document repository is from May. Why aren't new versions being sent to the ECMA repository?

(group directs WH to the latest version not in the ECMA document repository>

(googlers + facebookers arrive>

BE: wait there's more Googlers? We have to bring more Mozillans now... (I kid, I kid.)

AWB: At the last meeting we sucessfuly deluded ourselves into thinking we didn't need NoIn productions. We've been unconvinced, so I reintroduced them.

WH: I've been looking into this NoIn business

AWB: OK, well if you come up with a solution for it!

WH: I got my grammar verifier up and running again.

DH: Ollie spent a long time looking at them and didn't come up with a solution.

AWB: naked yield is supported. The assignment part is optional.

EA: for yeild*, the expression is needed.

DH: agreed

  • yield * wouldn't make sense without

AWB: WH brought up that you can't have a conditional reserved word, so what I did is ensure that yield is always a reserved word which, in contexts where it can be an identifier is treated as such.

DH: contextual reserved would would be another instance of feedback from parser back to lexer (a la slash); Allen's approach is more elegant.

BE: yes, it's the right tradeoff.

AWB: overall status: thanks to Dave, in the current working draft we're starting to bring in module grammar productions and semantics.

  • module grammar productions
  • module semantics
  • Confident in the progress

BE: we have a separate agenda item on this, yes?

(yes>

AWB: still hanging out there and need work

  • no work done on unicode regexp
  • no work done on updating regexp to web reality

LH: Last consensus on "web reality" was that it would be in an annex ...

LH: there's text ( strawman:match_web_reality_spec) that patches some rules.

LH: the reason we got hung up is we thought there might be some grander unification with the regexp unicode flag, and I don't know what the status is on that.

LH: we should integrate the web reality piece into the spec.

AWB: do we want to defer the Unicode part

BE: did we have someone identified to work on it?

(norbert>

AVK: I thought there was discussion that agreed what was in and what was out?

BE: If Norbert doesn't do it, it's not going to happen for ES6

WH: (Q about the yield)

  • Will allow yield as an identifier?

AWB: Yes

WH: This will break

(whiteboard)

yield * 1;

is that a multiplication or yield *?

AWB: (whiteboard)

YieldExpression := [inside a generator] yield aaugh this keeps getting erased

AWB: inside a generator function, "yield" is a keyword that introduces a generator expression.

WH: inside a generator, this ("/") will be a RE, outside it will be a division symbol?

WH:

yield /a/g;

is this yield divided by a? or yield a regexp?

BE: so this is like the regular expression delimiter, it's going to need to have feedback from the parser to the lexer.

?: If you're inside a generator, it's lexed as a regexp. If not, it's lexed as division.

DH: I think that isn't affected here, the lexer is always fed the parsing context; it's not an ambiguity because it's determined by context.

WH: What's "inside a generator"? What if you're inside, say, an arrow function inside a generator?

?: Then you're not actually inside a generator.

WH: But you need to lex the thing to parse the thing to find out that you're inside something nested inside a generator, so that's begging the question.

BE: split grammar at higher level, InGenerator, NotInGenerator, something something something.

BE & DH: use new tricks, e.g. parametric productions. Even NoIn, back in the day, we would have preferred to use those.

AWB: Yeah, if we have to do this for yield, I'd be happy to switch to parametric productions, since it avoids having four forms of the expression grammar.

BE: alternatives is to make generator bodies strict.

DH: We shouldn't make the users life worse just to make the spec easier.

WH: well we are prioritizing the user, think of syntax-coloring editors, they also now need to know these complicated rules, too complicated and they'll get them wrong.

DH: in practice editors get things wrong

BE: and then you can pull request against them so it's all good.

DH: new implicit modes will bite more often

BE: let and yield are reserved in strict mode since ES5

DH: Parameterized productions are the cleanest solution

BE: Much better to parameterize then to duplicate productions.

BE & AWB: let's do a smaller group on parametrizing the productions.

...

AWB: Is there a point on binary data?

  • Don't think we're going to get them in

BE: related to spec process, getting things done painless and in a rapid-release fashion. let's talk separately.

AWB: Status wise: no progress on Binary data Typed Objects proposal with regard to the spec.

RW: (clarified binary data vs "typed objects")

DH: binary data name is bad, "typed objects" better. Because typed objects as specced are not actually good for binary data.

Typed Objects (formerly known as binary data)

AWB: typed arrays and dataviews are in ES6 spec, "structs" are not.

DH: Dmitry is working on this, it's not 2014 yet, we shouldn't definitively say it's not going in.

AWB: well, I'm trying to manage expectations.

BE: Let's revisit after we get a little further with the other items.

4.1 Arrow Functions

BE: When I proposed Arrow Functions, the empty parameter list was made optional. The omission

LH: C# requires formal parameters?

DC: Who is asking for this?

BE: Community feedback, Domenic has mentioned it as well.

DD: Possibly due to CoffeeScript, but is nice to omit the parens where they aren't necessary.

BE: For this proposal, there is no issue in leaving the param list out


let foo = => ...;

x = (y) // note missing semilicon
=> z

BE: but nobody does this.

DC: A concern, x = y, as written without the parens...

x = y
=> z

(This is a valid Arrow Function: traceur-compiler.googlecode.com/git/demo/repl.html#let x %3D y %3D> z)

AWB: No parameters: no LineTerminator here?

BE: If someone began with an arrow,

WH: I'm fine with this being an arrow function, but don't want this to depend on line breaking. I consider the following to be legitimate:

    x = averylongid
       => foo

DH: This would introduce a new sigil that you'd have to worry about

BE: npm style is a thing. People actually put semicolons at the beginning of lines starting with + - / { [ (, this would introduce => to that list.

var i = "1"
;+i

WH: (laughter)

BE: you laugh, but people do this

WH: I thought I'd seen it all...

BE: Do we extend the short list of characters that can begin an ExpressionStatement

DH: It's not worth it

EA: I think it's worth it

BE: Writing "()" is too hard?

DD: It's ugly.

it("should do something, => {
    // ...
});

vs.

it("should do something", () => {
    // ...
});

DH: I'd prefer not to have the hazard.

AR, DC: Agree with DH

Consensus/Resolution

  • No consensus on removing the empty param list

4.3 Math.hypot

DH: The idea is that it returns the square root of the sum of its arguments, but we have 2 and 3 argument special casing.

harmony:more_math_functions

It's an offense to mathematics if it's not: "The square root of the sum of the squares of all the arguments"

Defend the pristine purity of math. If it's only a 2-argument function, that's OK, but having it a 2- and 3-argument function is not good, just make it an n-argument function.

BE: Jason Orendorff outlined these problematic cases... (see es-discuss)

DH: this is no good man.

LH: Should be variadic

DC: Programming in general is an insult to mathematics. Because what we call functions are not what they call functions. One convention we have in JS is that calling a function with three parameters is the same as calling it with two plus undefined.

DH: but not for variadic functions. Since we want it for arity 2 and arity 3, cleanest way is to make it variadic. If you have 2 cases, yo have n cases.

Consensus/Resolution

  • variadic
  • call ToNumber on all actual arguments
  • if one is NaN, no special behaviour, allow to fall out.

4.7 JSON.stringify and unpaired surrogates

esdiscuss/2013-September/033293

AWB: The concern is that JSON.stringify, as specified in ES5, if there is an unpaired surrugate

AVK: There's a bug in V8 where lone surrogates passed to the utf-8 encoder turn into CESU-8 byte sequences.

  • What is the defined failure space

DC: The new spec is code points, so it could be unpaired surrogates

AVK: So it's 16-bit code units

DC: Yes

  • JSON currently passes unpaired surrogates right through
  • Suggest escaping them

AWB: Only for unpaired surrogates

DC: Will get through a UTF 8 Encoder, but will blow up

AVK: If you want the surrogates to make a round trip, then escape them

LH: Seems like it's saying, in practice, JSON will only admit into a JSON document UTF8

DC: (Question about range of affected)

AVK: only surrogates are affected

LH: were people running into this problem in practice?

AVK: Right now, roundtripping unpaired surrogates does not work. We could fix this by escaping them.

AWB: But this is an incompatible change from ES5, since the length of the string would change to include \uXXXX (or \uXXXX\uYYYY) instead of the surrogate itself.

AVK: (whiteboard)

JSON.stringiyf("\uD800")

AVK: \uD800 is a single sixteen-bit code unit that is also a surrogate.

BE: this seems incompatible, so I say no

LH: this just seems like a single case...not sure why we'd patch just this case

AWB: this is about unicode/UTF-8 which is very common

LH: any time I serialize any JS string, I have this issue, JSON isn't necessarily what's in question

AVK: this is also about JSON as it's a network format

DC: why are people doing this anyway

AWB: e.g. because they're passing binary data as strings

BE: murphy was an optimist

WH: Note the CESU-8 spec, which is a mutant of UTF-8 that encodes individual surrogates individually (even if they're paired).

AR: if CESU-8 is bad, why isn't this fix bad?

AVK: you get subtle security bugs and it's incompatible with UTF-8. I don't really mind that we lose surrogates as I don't care about them

BZ: if you pass unparied surrogtates, you'll just get bytes. If people are trying to use the high bits to store binary data, there are going to be problems.

DC: the problem is that you're trying to pass 16-bit data through to UTF-8.

(binary data through UTF-8 requires separate escaping)

AVK: is a network format, it has strings

BE: JSON is more then a network format

?: If you want to pass binary data, just escape unpaired surrogates before serializing them as JSON.

WH: Won't work. JSON will escape the backslashes in the escape sequences and you'll get double backslashes.

Consensus/Resolution

  • No Change. If you want to use lone surrogates you'll have to escape them after JSON.stringify().

5.1 splice, cross-realm Arrays and subclassing

esdiscuss.org/topic/array-prototype-slice-web-compat-issue

AWB: (whiteboard)

let newA = a.slice();

AWB: it turns out people use this to make a copy of an array

In the general case, assume you have:

class SA extends Array {}

let sa = new SA(10);

sa.slice(1, 5);

// What does this return?
// - a new SA?
// - a new Array?

It seems to make sense that when you slice a SA, you should get a new instance of SA

WH: (recalling Mark's points about Caja(?) use of slice) Array.prototype.slice.call(a)

AWB: This all makes sense, but the problem came up: what if "a" came from a different realm? Under ES5, slice() always gives you an array from the realm from which the slice function itself was defined.

EA: the expecation that you'll get an array is flawed since you are just calling "slice" on an unknown object. "slice" could return 42.

WH: Not what I asked. I was asking about the common existing idiom of calling Array.prototype.slice.call on an unknown object to coerce it into something known to be the built-in array. This breaks that.


[].slice.call(a);

// This result will be an array from the [].slice.call realm

AWB: I've tweaked the spec to say:

  • If the constructor I'm using to make the new instance is in fact a built-in Array constructor (not a subclass) from any realm, it then creates an instance of the Array constructor of the slice function.
  • So it essentially does what ES5 does, but if it's a subclass it doesn't do what ES5 does, but ES5 does

RW: my concern was if NodeList was eventually to become a subclass of Array, what happens to existing code that does...

[].slice.call(nodelist);

RW: it may solve itself? (the returned thing has the expected "shape")

(returned thing IS a realm-local Array instance)

AVK: we're not going to change NodeList (we're still trying to maybe put Array in its prototype chain), we're creating a new thing, Elements, which will work great.

RW: A new thing avoid breaking the old things.

BZ: well note that HTMLCollection can never get fixed in any way.

AR: just to clarify, if I have subclassInstance.slice(...), I get back what?

AWB: a subclass instance

(yay)

WH: If we adopt this, what would be the new blessed way to coerce something to an actual Array?

AWB: ES6 has numerous ways to force things to be an actual Array (not a subclass) from a given realm. Anyone who wants to force it can do that.

BE: yes, Array.from, or spread, i.e. [...otherArray].

DC/LH: you're proposing a breaking change?

AWB: no, I'm actually removing a breaking change. For all existing cases, the behavior will be exactly the ES5 behavior.

WH: It is a change for the uses that expect Array.prototype.slice.call to coerce to an actual Array. They will need to change if they interact with any ES6 code.

(General concern to ensure the behaviour remains the same)

BZ: In the subclassing world, and I add method to Array.prototype, if I had an actual array, I will get an array from this realm.

BE: If the first arg to [].slice.call(a) (a) is an instance of a subclass of an Array in this realm, as constructor will be used, otherwise, use

BZ: if the realm of the thisObj and the method do not match, create it in the realm of the method using the stardard Array constructor there.

AWB: Agree

WH: How do you find the realm of a Proxy?

DH: really don't want to go in the direction of relying to heavily on the realm

BE: What are you using to construct?

AWB: it's constructor property

AR: Mark counts on this behaviour to ensure that he'll always get "clean arrays" from something that may or may not be "dirty". He could accomplish this by using a frozen version of the method?

AR: Concerned about the Array "redirection", different prototype depending on what you call slice with

BZ: If you're doing "a.slice()", there is no problem, the result is a new instance of the thing you called slice

RW: Right, the issue arises when doing [].slice.call(arguments), nodelist, etc.

AWB: And these aren't arrays

(arguing the meaning of subclassing in ES5)

AWB: BZ's proposal of matching the realm of the function with the realm of the constructor is probably the right way.

DH: Seems like creating a patch for a scenario

DD: But this is what user code would do, using this.constructor

AWB: none of these are guaranteed, where you can wack the prototype...

<strike>

Consensus/Resolution

  • When slice is call, what is the realm of the slice method and the realm of the constructor of the thisObj (since objects don't have realms, only functions do, we have to look up constructor).
  • If they do not match, create it in the realm of the method using the stardard Array constructor there. </strike>

DH: why not actually find out what realm an object was created in, instead of trying to infer it from this.constructor.

AWB: Is there any other way of creating an instance of this object without knowing what this.constructor is?

BE: In ES6, class B extends A {}

AWB: Need to know two things:

  1. How to query what the constructor object is
  2. What the protocol is for invoking that constructor

DH: So for slice, we have a default

AWB: Yes. Considering adding to collection constructors, a factory for creating

DD: Sounds like an unforgeable symbol that effectively is the same as .constructor, but can't be messed up like .constructor can.

DH: Object to something that is an approximation to what we want

BE: It's a reflective approximation

  • Implementations do not want

AWB: What I am proposing and BZ:

What is the realm of the object I would create?

Is the object going to create an Array?

BZ: Seperate the concerns, two conversations about creation:

  1. "How?"
  2. "What?"

WH: Are you expecting to construct or call

(back to "how")

AWB: In my proposal you check if it's a constructor

BE: Opposed to that

DH: Have you audited these cases, how does it work for them all? Does it work for them all, except this case?

AWB: Yes. (The fix for splice is the fix for all of them)

BE: You've added a new reflection on the constructor

  • Let's take this back and make it completely backward compatible

BE: I can write code that sets constructor, and now it works differently in ES5 and ES6.

AR: (mumbled something relevant)

BE: Don't think Mark would want the constructor check

AR: The dot operator is the root of all evil in JavaScript.

BE: I thought it was the NaNs...

AR: We've got a lot of evil.

DH: How much breakage are we talking about? Given the semantics Allen originally wanted?

AWB: under what situations does getting an array instance from a different realm break something? Well, if you've tweaked Array.prototype across your realms, that will make a difference.

BE: The odds are non-trivial that we'll break something

WH: If you're looking at the prototype of things, Caja will break. If you're looking at the constructor property, ES5 code will break for anything that has a custom constructor

AWB: Ignoring the Realm, unless we add some new operation on instances that reveal what Realm they are originally from.

BE/DH: need to go back and work on this.

Consensus/Resolution

  • Needs revision of proposal.

5.2 Evaluation Order and The [[Invoke]] Operation

DH: Yehuda was interested in this.

5.3 @@unscopeable

AWB: Inheritance?

ARB: Wrong to apply this across inheritance

AWB: Changed in r18

ARB: How was this changed?

AWB: Own property

The remaining question, do we lookup on entry of with block or for every access?

WH: which one is slower?

AWB: every access

WH: OK, let's do the slower one.

(general laughter and applause)

ARB: (question about lookups that occur up a prototype chain that might encounter an @@unscopeable)

DH: The semantics of with:

  • There is an object that we'll do all lookups on

We're adding to that:

  • Check the black list first

BZ: Consider you have two objects in your prototype chain, with two different @@unscopeable black lists

AWB: The first

ARB: What if you've put a "values" property directly on the instance?

RW: This was meant to fix that problem.

ARB/BZ: On the prototype, but what about an own property on the instance

(acknowledged)

ARB/DH: Discussion about predicted breakage.

BZ: Possibly as a descriptor?

RW: That was also considered

ARB: But if you [[Set]] it won't go away

var a = [];
a.values = 1; <--

DH: (Recalling the issue that created this problem)

function f(values) {
            ^----------------------+
with(values) {
values = 1; <-- is pointing to
}
}

But, if the parameter bound values object has a property called values, the values access INSIDE with(){} is accessed.

RW: The case that hits @@unscopeable in its current form is far on the edge. Ext.js is generally an outlier in their use of with(){} (in a world that's continuing to progress towards strict mode). Future versions of Ext.js won't have the offending with(){} code, so it won't break on @@unscopeable. Ext.js has also committed to evangelising and getting the patched code out to clients, it was just a matter of needing time to do so.

AWB: Someone could have created his own Array instance with names that @@unscopeable would hide. This would be also not be compatible.

BE: This is why I find find/fill kind of short, you might get collisions. ??

AVK/EA: But but but DOM

BE: Don't rush!

BE: Gecko did ship Array.prototype.values and backed out which is why we added @@unscopeable.

BZ: In the DOM we want Element.prototype.remove and friends which are problematic due to event handlers, which use with semantics.

BZ: You could have a proxy that does the same thing.

AVK: Ouch.

ARB: When an access occurs in with(){}, and a property is found, look at the @@unscopeable on THAT object

DH: Do we want to blacklist names or name-object pairs.

  • Distinguish between allowing instance properties

BE: How does this change for MOP?

AWB: Changes from Get to GetOwn, etc.

BZ: DOM Proxies are nicely behaved.

...

AWB: Is anyone actually going to implement?

DH: This is easy for SpiderMonkey

ARB: This is easier then the previous.

BE: Concerns about changing the Identifier resolution for Proxy

AWB: Only for with

DH: If you want to not bypass the proxy mechanisms, you have have to give them a new trap to define how they behave when [[Get]] in with(){}

BZ: Have to give Proxy a way to know that it's happening in with(){}

(working through issues with document.forms)

hasOwn on @@unscopeable

DH:

  • Walk the prototype chain
  • foreach one,
  • check if it hasOwn @@unscopeable
  • hit a proxy, does the same

...This prohibits Proxy from participating in the object operation.

WH: Summarize?

BE: We have a problem adding names to mature the API. Let's move forward with @@unscopeable

AWB: For the @@unscopeable arrays I specify in the specification, should they be frozen?

DH: No, need to be able to polyfill feature additions.

AWB: You could always replace the array object.

BE: When in doubt, don't freeze. Why isn't it a Set?

DH: put down the freeze gun. Put it down.

EA: Set is the right answer, semantically.

AWB: Yeah.

DH: I don't really care.

AWB: You asked for a Set no, I think it should be a Set.

Consensus/Resolution

  • Continueing with @@unscopeable, with changes w/r to lookup to be defined.

  • Noted change:

    • When a property is found, look at the @@unscopeable on THAT object
  • @@unscopeable

  • a Set

5.5 Math.roundFloat32

AWB/DH: Offline discussion to rename to something more Math object familiar

Suggestions:

  1. Math.fround()
  2. Math.f32round()
  3. Math.roundF32()

DC: This isn't a round operation

DH: It is, according to IEE 754

BE: fround. f means float, i means integer

AWB: What this effectively does, is "round" (observably)

Consensus/Resolution

  • Math.fround

5.6 Backwards compatability, Unicode UTR31, and ES identifiers (U2e2f)

esdiscuss.org/topic/backwards-compatibility-and-u-2e2f-in-identifier-s

AWB: Traditionally, ES has said that Identifier are composed of unicode characters. There are changes to Unicode that rescind it's ability to be an Identifier.

AVK: According to Norbert, the character in question was not part of Unicode 3.0 and therefore not a change

(group testing identifier creation with U2e2f)

Consensus/Resolution

5.7 note in 11.6 WRT Unicode versions, update to Unicode 5.1

people.mozilla.org/~jorendorff/es6-draft.html#sec-11.6

AWB: (Norbert proposal)

Consensus/Resolution

  • Remove: "NOTE 2 If maximal portability is a concern, programmers should only employ the identifier characters that were defined in Unicode 3.0."

5.8 line terminators in template strings. Should they be normalized?

(discussion re line terminators)

AVK: HTML parser does normalization, but e.g. DOM setters do not

BE: not normalizing would introduce more interop hazards than we want.

AWB: just to be clear, this is both cooked and raw form.

BE: yes. Add \r\n to the list of special things, alongside closing backtick and ${

  • Propose: CR and CR+LF are canonicalized

AR: why isn't this just part of the data? Why canonicalize?

BE: it's not a byte string, it's a string.

BE: but raw should be raw

DD: no but then you have an interop hazard, because people will write code that works great on Unix, then some poor Windows user ends up with \r's in his strings that the Unix-using author did not anticipate.

BE: but you should be using cooked

DD: but a lot of the examples, e.g. on the wiki, use raw

BE: ah right, like the regex one, because you need all those slashes. Hmm.

BE: Python normalizes, Ruby normalizes

Consensus/Resolution

  • Normalize CR, LF, and CRLF to LF [WH: Is this consensus recorded correctly? I understood the consensus to be normalizing all lexical grammar LineTerminatorSequences to LF.]

5.9 12.2.4 note says we decided (Jan 2012) tail calls only in strict

mode. Is this still correct?

harmony:proper_tail_calls

DH: function.arguments is poisoned in strict mode. This opened up doing tail calls.

LH: Are the tail call locations on the wiki still up to date?

DH, AWB: yes, to the best of our knowledge; let us know ASAP if there's something wrong with them.

  • Discussion about tail call location opportunities

AWB: getting close to the point of getting tail call stuff into the spec (depending on how busy Dave keeps me); any comments appreciated sooner rather than later.

AWB: Implicit calls to accessor properties in tail positions, e.g. return x.y, and x.y turns out to be a getter, do we want this to be a tail call.

return x.y;

If x.y turns out to be a getter, is that a tail call?

AWB: also consider return x.y() where x turns out to be a proxy; then it's not just a simple call, it goes through the proxy handler.

DH: More generally, if anything, syntactically not a call, turns out to be a call, do we include that as a tail call?

DH: basically, is the spec mandating something that makes too much work for implementations. The definition of tail position is not in question; it's the semantics of what things in tail position become tail calls.

LH: Function calls?

AWB/DH: and method calls

AWB: Calls in general

WH: new?

DH: no, new doesn't really work, because of the IsObject check afterward.

AWB: OK, what about the proxy case.

DH: I think it works fine; the semantics is just tail-calling the call trap.

STH: I agree with Dave; we're just making a tail call to some arbitrary code. The code we're worried about is in the call-ing function, not in the MOP operation/trap handler.

Consensus/Resolution

  • Yes, the list is still correct.
  • function.arguments in non-strict makes tail call effectively impossible.

(increasing insistence on break time)

AWB: but let's do point 5.11.

5.11 Disallow? let undefined; const undefined; class undefined {};

module undefined from "foo";

No one thinks that disallowing this is a good idea.

Consensus/Resolution

  • Allow

BE: Let's make it a keyword inside generators! Just kidding.

4.2 Reconsider decision to make Typed Arrays non-extensible

esdiscuss.org/topic/non-extensibility-of-typed-arrays

AWB: Last f2f we decided to make typed arrays non extensible.

ARB: Chrome makes them extensible but I'm in favor of making them non extensible.

AWB: the most significant thing I saw is that if you create a subclass of a typed array, the reason for doing so might include adding some additional state, and so the only direct way to do that is by adding own properties to the instance of the subclass, and if typed array instances are created non-extensible, then subclasses couldn't do this.

DD: You cannot add indexed properties to typed array. It would be surprising if you could add identifier name properties.

DL: There are no objects in JavaScript that have this behavior right now.

OH: Certain restrictions exist for numeric properties. There is no other object that doesn't allow you to add an expando.

OH: Neutering is a performance issue as well. If we should make decision based on performance we should kill neutering.

BE: the real issue is not performance (although the thread may have misdirected in that direction).

AWB: we could go back to having numeric expandos, if you want...

BE: No no no no, there was a performance counterargument there, unlike for named expandos.

DL: (clarifying

A = new ArrayType(uint8, 10);
s = new StructType({a: A, ...});
a = new A();
a.foo = 5;
s.a = a; // ??
b = s.a

DH: A "Typed Object" is effectively a pointer to a shared backing store. If those objects can carry addition state

OH: If

DL: With typed objects we can do

Uint8Array = new ArrayType(uint8);

AWB: There may differences between TypedArray types

...

DH: There's an example, wherein two views on the same backing store will not be === or ==, but there are implementation strategies that could make it possible.

STH: It's easy to use getters where writing to one

I'm behind....

OH: Structs aren't expandable so therefore Typed Arrays shouldn't be expandable

BE: Do we need extensible array types

DL: All variable length array types to be extensible?

AWB: We'd have to have a form of class, whose instance properties are defined by a Typed Object

DH: Foresee a mechanism

WH: Prefix properties?

DH: Yes, if you have super type, its subtype is

OH: Index properties are seen first in ForIn

DH: Recalls discussion to allow index names to diverge, object model reform, etc.

DH: most beginner references establish that all properties are strings

RW: There is a lot of attention paid, in learning resources, to establish Array and Object as two different things, based on their property name "type". It's not until much later that realization is made that they are the not different, aside from special length property behaviour.

ARB: not allowing them is more conservative for now. We can always relax them later.

BE: that conservative argument seems strictly stronger than consistency arguments which always pick their preferred dimension of consistency.

WH: I haven't seem any good arguments for allowing expandos in arrays but not structs.

BE: the arguments are: it's useful; it works on arrays.

AWB: as currently specified, you can create a subclass of Uint32Array.

(Discussion of how buffer semantics work in subclasses. Decided it's not really relevant.)

AWB: the subclass wants to add new properties

DD: but it's OK to add prototype properties...

AWB: yes, but, most people represent per-instance state with own properties. Yes, you could use a weak map, that's the universal answer, but that's not what people do currently in JavaScript.

WH: composition over inheritance

AWB: but then you don't get any inherited behavior

AWB: Here's what I would advise. Use composition when you're composing base abstractions into a new abstraction. But if your new thing is a specialized kind of array, which may need some extra state, then that's not a composition type of situation, it's an inheritance type of situation.

DH/AWB: we could not make @@create create a non-extensible object, instead we would make the typed array constructor call Object.preventExtensions on this.

WH: extensibility breaks compositionality.

AR: this is a strange argument; you serialize and deserialize the object, losing expandos seems fine.

BE: serialization/deserialization is not the model.

DD&DH: so if you don't call super, or wait until the end of the constructor to call super, the constructor can extend with per-instance properties

OH: Have @@create produce an extensible object and have the constructor call Object.preventExtensions

DH: Yes

DH/AWB: What order does super get called?

DH: Seems like a solution, but not one that everyone is fully in support of.

DH: Points are not about speed of accessing properties of objects and more about layout of objects

BE: Most users of typed arrays are not naive. We should not be promoting these overal normal arrays.

AWB: Not even numeric?

BE: Define numeric. Unless you actually know what you're doing, you shouldn't be using these and we shouldn't be promoting them for these.

BE: Typed arrays are power tools.

(Float-containing normal array is almost equal in perf to float64 typed array in JavaScriptCore.)

OH: Agreed.

OH: Transfering large amounts of data to a worker.

??: Better not have any expandos.

BE: How do we make progress? Stand-off!

DH, WH: to be clear, it would be sad if typed objects and typed arrays were inconsistent. so if we say typed arrays should allow expandos, then so should typed objects.

DH: You can't put a variable-sized array in a struct.

OH: Do we have a ToArrayIndexedProperty somewhere? Might have been internal to JavaScriptCore.

AWB: The problem here is what array index meant when there was only the built-in array type doesn't fit with the typed array usage we have now.

BE: I don't see it.

Straw poll: 8 non-extensible, 8 mu (abstain), 1 (Ollie) extensible (I think it was moo, way more of a cow sound.) ( en.wikipedia.org/wiki/Mu_(negative) )

OH: We don't see any reason to remove extensibility, you can always make them non-extensible

OH: The view of the JavaScriptCore team is that making them non-extensible removes what developers can do, whereas making them extensible does not have to cost and provides more freedom.

OH: examples of behaviour equivalent to TypeArrays with expandos:

array = [1,2,3]
Object.defineProperty(array, "length", {writable:false})
array[3] = 0;
array[3] => undefined

Various DOM lists allow non integer expandos, but don't allow integer expandos

BE: The conservative argument is that if we're unsure we should make it non-extensible so we can make it extensible later.

AR: You can interpret it both ways.

DH: Non-extensible is conservative because you can change it later. It being extensible cannot.

DH: Extensible is probably my preference at this point, but we can't leave it unspecified.

BE: Due to duplicate bug of bugzilla.mozilla.org/show_bug.cgi?id=695438 -- namely bugzilla.mozilla.org/show_bug.cgi?id=828599 with its adding .stride to WebGL vertex typed arrays -- I am now in the extensible camp.

Straw poll:

Extensible: 10 Non-extensible: 6

STH: (points about the mental model of operating on the backing store)

DC: (points about the hazard of user code that abuses Array and creating a new hazard)

Consensus/Resolution

  • Consensus deferred.
# Rick Waldron (11 years ago)

Sept 18 Meeting Notes

John Neumann (JN), Dave Herman (DH), Istvan Sebestyen (IS), Alex Russell (AR), Allen Wirfs-Brock (AWB), Erik Arvidsson (EA), Eric Ferraiuolo (EF), Doug Crockford (DC), Luke Hoban (LH), Anne van Kesteren (AVK), Brendan Eich (BE), Brian Terlson (BT), Rick Waldron (RW), Waldemar Horwat (WH), Rafael Weinstein (RWS), Boris Zbarsky (BZ), Domenic Denicola (DD), Tim Disney (TD), Niko Matsakis (NM), Jeff Morrison (JM), Sebastian Markbage (SM), Oliver Hunt (OH), Sam Tobin-Hochstadt (STH), Dmitry Lomov (DL), Andreas Rossberg (ARB), Matt Sweeney (MS), Reid Burke (RB), Philippe Le Hégaret (PLH), Simon Kaegi (SK), Paul Leathers (PL), Corey Frang (CF)

4.2 Reconsider decision to make Typed Arrays non-extensible (Cont)

RW: (recapping yesterday's discussion)

EA: Can we pick 3 people to champion a recommendation?

RW: Ideal

(support in the room)

Consensus/Resolution

  • 2 People to come back with a recommendation:
  • Dmitry Lomov
  • Allen Wirfs-Brock

Post meeting update: Dmitry and I discussed the issue and our recommendation is that Typed Array instances should come into existance being extensible. This is only about the objects created by the current set of built-in typed array constructors (or any subclasses derived from them). It does not imply that fixed size array types introduced by the future typed objects proposal will necesarily also be extensible. -- Allen

4.4 Symbols

Dave Herman presenting (follow up slides)

DH: Symbols: object or primitive?

Open issues: - privacy - object or primitive

(1) Statelessness

  • Symbols should not share state
  • Encapsulates key and nothing else

(2) Cross-Frame Compatibility

obj[iterator] = function*() {};

Another frame must also know what this iterator symbol is

EA: Workers?

AWB: Only an issue when you want to move a value...

EA: Case where you use a name as a brand (branding using public symbols do not work. Branding needs true private state.)

YK: can these be structure-cloned?

(3) Methods

DH: The one place that most objects can't have methods is prototypeless objects, but they can have instance methods. For most most of the interesting data (strings) there are things you can do on them:


alert.call();

Math.sin(0);

document.getElementById("body");

DH: if you only allow things to work via functions with arguments, you are turning off a powerful tool

(4) Mutable Prototypes

Monkey-patching standard methods is a best practice

The evolution of the web depends on it

DH: This is important to the language

DH: mutable prototypes are the way that developers provide a consistent platform across user agents they don't control

STH: This is assuming that Symbol will grow methods

YK: It's actually an assumption that it won't

DH: If we freeze a prototype, we're closing the door to ever evolving the API and closing the door to user code experimenting

  • No experience to show that freezing a prototype "works"

WH: By "mutable prototype", you mean add and change methods, not change the prototype

DH: Yes, changing the shape of the prototype object

AR: (general defense of mutability, in prototypes and otherwise)

AWB: Freezing the prototype can be undone safely, if there is reason in the future.

AR: this is not a conservative position, despite the claim.

DH: It doesn't matter, if we design depending on the invariance that the prototype is immutable then we can't change

(5) Non-Answers

(6) Shallow-Frozen Objects

O.getPrototypeOf(iterator).foo = 12;
  • Fails Desideratum #1: is stateful
  • Fails Desideratum #3: distinct cross frame iterators

WH: What doesn't work?

DH: The standard iterator symbol would be different in different frames because they exist in different heaps

(6) Deep-Frozen Objects

O.getPrototypeOf(iterator).foo = 12; // strict error
  • Fails Desideratum #4: no evolution

YK: How does the current spec deal with the function.prototype linkage

AWB: The prototype is null

DH/YK/AWB: this is incoherent, doesn't work at all.

(7) Missed? Something about prototype-less wrappers, fill in from slides...

(8) JS already has an answer for this! Autowrapping of primitives

  • typeof iterator === "symbol"
  • Get/Call operations auto wrap
  • Prototype state is global per-frame

"People think auto-wrapping is gross"

  • provides uniform OO surface
  • does so without runing immutability
  • doesn't ruing API patchability
  • need a solution for value types

(9) Remaining Issues

  • [[ToPropertyKey]] of Symbol objects" auto-unwrap? Does it matter in practice?
  • Worry about toString for symbols and Symbol objects? Does it matter in practice?

WH: We should be consistent with the way we already do things. We don't unwrap boolean wrappers when used in a condition; we shouldn't unwrap symbol wrappers when used to look up a property. If you use Boolean(false) in an if statement, it will evaluate true.

AWB: In ES5, there was special treatment of wrappers, e.g. in JSON.

  • no reason you should have a wrapper value in most contexts
  • I would say, don't use

YK: Is it important that === works cross frame or just the indexing

  • Have a mechanism that allows them to

DH: A kind of object that overloads ===

YK: No, don't

  • If you go with new Symbol() returns object with mutable prototype

DH: No "object" solution works because of methods

  • Need to move to next slide
  • w/r to toString, I can't construct a plausible scenario where this would be encountered

YK: Accidentally construct a wrapper

WH: People explicitly convert to string before doing an operation. It would be impractical to make symbols survive the various kinds of string conversions.

ARB: Lot's of existing code that has code paths that converts a value to a string to get property key, would subtly misbehave with implicit symbol-to-string conversion

(10) typeof Extensibility

We don't know that it wont break the web

MSIE "unknown type may simply be rare enough to be undiscovered.

Fallback: "object" with [[Get]] et al that behave like auto-wrapper? (Object.isValue()?)

WH: It won't break the web because existing scripts won't see the new type. Seeing one of these things requires changing the script. WH: We said that array subclasses are new and safe because unmodified code won't see them break things like Array.prototype.slice.call; why isn't the same argument applicable to symbols?

AWB: when I did symbols originally, as primitives and not wrappers, it was a bug farm, because everywhere that assumed a primitive type, now had to explicitly account for the possibility of a symbol. The standard library in particular had to do this. In practice, anyone who is writing a general-purpose library would have to do the same thing. If you have wrappers, then the value "turns into an object" when you use them as such, which works fine.

ARB: I implemented symbols in V8 with wrappers and there were no places where they needed special handling.

AWB: yes I agree! Wrappers address most of the issues.

YK: (Concerns about existing code that might not be resilient to typeof)

DH: the most straightforward thing to do is extend typeof, but you can have code that's not resilient to new typeof values.

(More discussion of existing library code having to deal with symbols).

DH: Many new things in ES6 are objects with new APIs, so passing them in would violate basic interfaces expected. Whereas for typeof, many APIs will take any value whatsoever, and then figure out what to do via discriminating via typeof. So introducing a new typeof will break their assumption that they can handle any case.

JM: I don't think it's so different; they will fail in similar ways.

AWB: This is different; it's at the core of the language, and there is a different expectation.

DC: Yes, this is different. There is an idiom that will fail, and it's a common. switch (typeof something).

DH: if the only conservative extension guarantee we can make is that if you don't use any new features, everything is fine...

DH: the difference is that there are APIs that say "I'll take any JavaScript value," they don't mean "I'll take any JavaScript value that was present in the ES5 era." This is different from saying "I'll take something with an array interface," and you passing in something like Map which happens to violate the array interface.

WH: you are picking the wrong strawman. We are introducing things that do keep to the array interface (array subclasses) but break existing idioms such as using Array.prototype.slice.call to coerce to an Array object.

DH: right, I'm picking Jeff's strawman, not yours.

AWB: the issue with slice() is about realms, not kinds of objects, or subclasses.

WH: The slice problem is not about realms. It arises merely if you introduce an array subclass and never use more than one realm.

WH/AWB: (arguing about what they're arguing about)

JM: You say it's clear when you pass in the wrong interface to an array-expecting vs. an all-expecting. Can you expand on why that's clear?

DH: Difference between an api says "I will take an arraylike thing" and I will operate correctly and API that accepts "any"

JM: but it's not about types for the "any" APIs; they usually just pass them through, e.g. a datastore API.

LH: Rare that any API says "I'll accept any"

DH: we're talking about parametricity, passing through the value vs. inspecting it. My experience is that I see type inspection of the type-any inputs a lot.

LH: How often does an API take type "any"

DH: A lot of JS programs don't protect against wrong values

WH: No such thing as an API reliably taking type "any" and portably doing anything useful with it. Suppose we later introduce a new Decimal primitive that obeys the IEEE standard in that a DecimalNaN is not === to itself. Would a map work with it? Code that exhaustively type-dispatches primitives simply must change once in a while.

YK: (recalling a point AWB made) people using typeof to defeat autowrap, tell the difference between a thing that auto-wraps and a thing that does not

DH: The reason we shouldn't be afraid, is typeof of serves the purpose ...

EA: If typeof primitive symbol returns "object" there is no way to distinguish a primitive symbol from a wrapped symbol.

DH: we'd have to add a gross check for distinguishing

  • slipperly slope

WH: "the future is bigger then the past" and it seems we're trying to perpetually mortgage the future to fix a relatively transitory fear we're not even sure is real. The cost is forever having yet another mechanism to distinguish the types of primitives.

DH: Then there is the "browser game theory" argument, who will implement in the face of danger first?!

WH: (interrupts)

DH: I also like finishing my sentences. I'm willing to give it a try, but...

EA: FWIW, V8 is shipping typeof symbol under a flag and no bug reports

DH: under a flag is not the web

  • Willing to take this back to SM implementors

AWB: Explicitly checking for "object"

DH: Existing code breaking, this needs to be considered.

  • New code can find old code that can be fixed

RW: Will put Symbol through jQuery in test suite to see what "breaks"

Agreement that auto-wrapping is the way to go

WH: Yes, use auto-wrapping the way we know it

re: toString

DH: One way or another we'll have to have it, whether it throws or produces a string

DH: There are values that throw, like proto-less objects

  • conversion to string is not infallable in JavaScript

ARB: implemented two toString methods

  • Symbol.prototype.toString => throws to avoid the implicit coercion hazard
  • Object.prototype.toString => applicable to Symbol, but have to be explicit

AWB: Plausible that Symbols could have a printable "name"

DH: Proposal summary:

  • Symbols are primitive
  • typeof is "symbol"
  • standard Symbol prototype
  • construct to create wrapped symbol
  • Symbol wrapper object does not auto unwrap. ToPropertyKey will eventually call Symbol.prototype.toString which will throw.

ARB: for the record: that is exaclty what V8 implements

YH: to the implementers in the room, please make the error message when you use a wrapper very nice.

ARB: V8 gives explicit error message

DD: new Symbol() is a probable footgun; should it do anything at all? Maybe just throw? Because we don't have symbol literals, so unlike new Number(5) vs. Number(5) vs 5, the choice is not obvious; people will try to do new Symbol() not realizing that this creates a wrapper.

RW: Agree.

ARB: but then it's weird that there is an object you can get access to, but whose constructor doesn't actually work.

DD: but the only way you can get access to these objects is via the this value inside Symbol.prototype methods, in sloppy mode.

DH: no, Object(primitiveSymbol) would give you back the wrapper.

DD: ah, damn.

AWB/ARB: Discussing valueOf returns, used in contexts where a numeric value is expected

DC: But string.valueOf produces strings

AWB: Do you anticipate future value types having auto-wrapping?

DH: BE has thoughts about typeof modifyability

RW: Defer until BE is present.

Agreement

AWB: How does user code define a "well known Symbol"? One that works across Realms?

DH: not sure

  • Standard library, we can create something that exists everywhere
  • Library code, not sure

ARB: Think this is a serious problem that needs to be addressed

DH: Proposal

  • Agree that it's bad to have a Symbol with BOTH a private and public form
  • Private by default? Public by access?
  • Need to solve the remaining proxy leak problem

AWB: We've discussed and concluded that we're nowhere near a solution to the private state problem.

YK: Mark's solution inverts where the transaction occurs

DH: If private symbols really behave like WeakMaps and you invert where they live, then they are truly private

YK: You want the proxy to trap them.

Why?

AWB: It's just a property name.

DH: If you have access to the symbol

EA: What about iterator?

STH: If you want the proxy to have iterator behaviour, you need access to @@iterator

...

AWB: Mistake to conflate symbols, which are guaranteed unique property keys, with private state. There is a temptation to do it, but we run into problems. I want private state, but there are better ways to do it.

DH: I am pretty exhausted from years of this debate, but from all the things we have to decide, this has to be decided now. And I am willing to fall on either side of the fence (private vs. public vs. both), for the sake of resolving this, but we need to resolve it.

LH: agree; we can't leave this meeting without a decision on this. But Arv's proposal (GUIDs) does give us a path.

AWB: but Arv's proposal doesn't solve privacy at all; it's just about the representation of symbols (strings vs. real symbols).

RW/DH: strings as symbols have bad usability and problematic to use.

YK: No solution to the enumerability question (are symbols enumerable)

DH: yes, if we were going to go with this, we would just have iterator and create be a shitty string.

YK: worse, it would have to be a UUID published in the spec.

AWB/DD/AR: underscores are better than GUIDs.

DD/RW: Symbols not for private state, use a WeakMap. Symbols for uniqueness, move on.

DH: Arv, what is your issue with just having public symbols?

EA: they don't carry their own weight. They behave like strings, except for reflection.

(silence)

AWB: there is one difference. They are in a different meta-level of the system. There is no way that user data can coincidentally be confused for a symbol.

DD: also, symbols do not show up in JSON.stringify.

DH: This allows us to add a meta level. Just like __proto__ in the past. Underscores are, until now, our magic feather that we wave around to say "This is the meta-level! This will not be confused with data!" And that's BS.

LH: unless you enforce the distinction, people will build abstractions that break through the layers.

EA: before we had for-in; then we gave people getOwnPropertyNames and people started using that; now we're going to give them getOwnPropertyKeys and they'll use that.

discussion about the string display

YK: debugger could recognize that it's a uuid and replace with a readable value

discussion about "__" names.

LH: if you use any english word, someone could create a conflict. If you use "__", there is no accidental conflict.

YK: Using "iterator" or "iterator", no one can reliably ducktype for an ES6 iterator

STH: leaving for lunch, in favor of Symbols

EA: I'm still in favor of keeping symbols, sorry for derailing the discussion a bit; what helps is the possibility of removing getOwnPropertyKeys. That makes them secure in the absence of proxies.

LH: but then existing libraries cannot implement a real mixin that moves symbol-keyed properties over to a target object (if symbols aren't given reflective capabilities)

(Brief discussion of making Object.mixin be the only way to do this.)

DH: Object.mixin that can transfer symbols plus proxies allows you to reimplement Object.getOwnPropertyKeys.

AWB: Still think we should have Symbols, getOwnPropertyKeys

WH: I object to getOwnPropertyKeys (because of too many historical layers: in every spec we seem to be adding yet another layer of enumerating the properties of an object with a we-really-mean-it-use-this-one-instead-of-the-previous-edition's vibe).

DD/AR/DH: (discussion of Object.mixin + proxies trick.)

YK: It sounds like we're slipping down the path of doing privacy with symbols again, and we're going to appease people for the wrong

LH: the concern for getOwnPropertyKeys is that people would just use it in place of getOwnPropertyNames. Maybe if we separate into getOwnPropertySymbols + getOwnPropertyNames that will make it sufficiently painful that people won't just use getOwnPropertyKeys together.

Consensus/Resolution

  • Symbols are a new primitive type with regular wrapper objects
  • typeof symbol === "symbol"
  • implicit conversion to string throws
  • new Symbol throws
  • Symbols are public, not private ok that they leak to Proxy
  • Symbols are unique
  • Only exposed via Object.getOwnPropertySymbols instead of Object.getOwnPropertyKeys
  • Object.mixin copies both symbol and string properties

Additionally:

  • AWB commits to bringing a proposal for user defined well-known symbol registration

6. Post ES6 Spec Process

(Rafael Weinstein) - slid.es/rafaelweinstein/tc39-process

RWS: put together some thoughts after the last meeting with DL, EA, AWB, etc.

RWS: most of it is good except that it's date driven and the consensus requirements lead to a high-stakes game for getting features into the game.

RWS: The second problem is that with large-quanta spec releases, there's a varrying maturity level for proposals. Stable stuff is "held hostage" to newer features.

RWS: as we near a release, we end up with large pressure around things which may or may-not make it. Argue that this is destructive to feature quality.

RWS: we also have an informal process. It occurs to us that acceptance of features comes before details are sorted out. Implementers, therefore, lack a clear signal about when it's time to start implementing features. Might be unavoidable, but other groups show a different way (W3C, e.g.)

RWS: we also have a single spec writer who bears the full burden of authoring spec text.

RWS: a few ideas:

  • decouple additions from dates
  • put structure around stages of maturity
  • what does each stage mean? Get clarity

RWS: non-goal: componentize the spec or break apart responsibility from the whole group. Also a non-goal to change the rate of evolution (necessarialy).

RWS: looked at how the W3C works and tried to extract the bits that seem to work well. A 4-stage process: 1.) proposal 2.) working draft 3.) candidate draft 4.) last call

RWS: At a (much more) regular interval, we'd post (smaller delta) drafts to ECMA.

AWB: do these stages line up with W3C terminology?

(sort of, not really)

RWS: proposals outline the problem, need, API, key algorithms, and identification of cross-cutting concerns. Also, and identified champion. Acceptance signifies the idea that the solution is something the committee wants to keep working on.

RWS: note that we don't explicitly slate a specific revision is targeted for a proposal. That comes later.

AWB: concerned that we might accumulate accepted proposals that there's no activity on. How can we structure a cull?

BE: as needed. FileSystem API as example.

RWS: the analog might be the "deliverables list" used by W3C -- removing something from the list on the wiki could be that thing

DH: Not to componentize? Seems like there is something of a componentization and that's the value?

RWS: don't want to abandon the goal of language coherence. CSS did this wrong and have lots of weirdness as a result. Non-communicating editors lead to pain. This model is different: everything merges into a single spec.

DH: how is this different to what we're doing now? Maybe this is a smaller tweak?

BE: What this does is adds more staging before "proposal"

RWS: this is saying the first stage doesn't have spec text, but the second stage does.

DH: Makes a lot of sense, might make sense to spell out the earlier "incubator" stage.

RWS: so there might be a stage-0, which is sort of the strawman we've had before

RWS: what we want to see at stage 2 is draft spec text. It can have early-quality notes, etc. but thought should be put into the text for the feature before we collectively accept the feature.

RWS: there are a couple of key things to look at: can we decouple spec editions from specific features? what are the substantives stages of maturity?

BE: quick question: the i18n spec was on a different track, is this only for core stuff (quotes FakeAlexRussell??)

(sort of, might be a way to draw stuff into the main spec)

RWS: stage 3 is the "Candidate Draft". It signifies that the committee thinks the scope of the feature is set. We can incorporate changes, but the key thing is that implementations are potentially costly. This stage is a green-light for implementing and final feed-back

RWS: stage 4 is "last call draft". 2 implementations and an acceptance test that they pass. Once accepted at this stage, the draft can be scheduled for the next spec to be published.

RWS: what about dependencies? The committee isn't absolved of this. IT's up to us to manage them and there isn't any silver bullet. We need to make decisions.

RWS: thought a lot about linkage as a part of this. A champion's interests might work against the language (ducking dependencies, etc.). The committee still needs to advise and continue to look over the landscape.

(discussion)

AWB: implicit in this is redefining the role of the editor to be more of an EDITOR, and less of an author. Should probably have a role in advancing proposals.

RWS: so still a world where there's a single editor?

AWB: yes.

(general agreement)

PLH: Noting that some of the process order might be confusing/out of order, with regard to naming?

RWS: yes, "last call" means somethign different in W3C that doesn't map well

YK: the year might be a red-herring. The point isn't the date and the goal isn't to rush things under the wire.

RWS: (refers to Chrome release process) (not quite Chrome, but close and relevant: developers.google.com/v8/launchprocess )

AWS: some of the non-technical overhead can be offloaded

DL: part of the goal is to help offload the work, getting more people writing more spec text.

(notes that this happened for Proxies and O.o)

DL: inside the v8 team, we don't have a ton of visibility into the maturity of features.

BE: spidermonkey has shipped many things over the years, but at a cost

(discussion about implementations and style)

RWS: so we can imagine that you'd have different styles of implamentations at each stage? Makes sense.

(agreement)

AVK: the w3c is removing the last couple of these steps

PLH: there's a new draft on github somewhere

(some discussion that you need implementations, hence the new W3C process)

AR: the chrome process shows that some features might slip multiple features, and that's very good for overall quality.

AWB: are the criteria here entry or exit criteria?

(discussion)

WH: What about mutualy beneficial features?

AR: that's the dependency question, we talked about that

RWS: it's sort of arbitrary, but that exists no matter what. There's no silver bullet. It's the job of the committee to keep an eye on what's in flight. Not sure a process can ensure that we can do that well or poorly.

WH: not componentizing is good, but want to make sure that the process doesn't get in the way.

BE: true.

AWS: if we see things that are tightly linked, we might treat them that way

RWS: as I said earlier, the committee can choose to merge them

WH: is the intent that the spec will be written by many people? or a single author?

RWS: the hope is that we'll have more authors for sections of the text, and it'll continue to be the responsibility of the (single) editor to maintain quality.

YK: I've found it useful to go throuh the exercise of writing spec text

LH: I like that aspect of this proposal quite a lot

DH: I've found it useful to write things in pseudo-code when exploring many alternatives...there's a cost for writing it out that way

AR: things are meant to get more "specy" and improve in quality over time

(Reviewing previous approaches to specificying new features)

BE: I think ES7 should follow this

AWB: Yes

STH: As long as we're realistic about how much process change can really be helpful

DH: Smaller features can ship and large pieces can take the time that they need.

DH: need a way to post features in progress

WH: Difficult to do refactorings the spec if various folks write parts of it independently.

BE: Integration step left out? (eg. when does feature integration to the spec occur?)

  • huge costs
  • potentially huge conflicts
  • need to identify necessary changes early as possible

WH: Concerned that the one-edition-per-year timeline is unrealistic both for us and for our users.

WH: Once-per-year would be too much of a moving target for users. For example, writing (and re-reading) books about ECMAScript would be difficult.

WH: Imagine trying to fast-track one edition per year through ISO, with yet another one done in ECMA by the time the previous one gets done in ISO. Also note that ISO has been known to generate interesting comments.

??: We don't need to send every edition to ISO.

??: Yes we do. They don't like it when you update an existing ISO standard and don't send them the update.

??: ISO likes their specs updated once every three years.

WH: How many simultaneous internal versions of the spec (the master Word document) would we maintain? Three?

AWB: One.

WH: Really? Let's say we'd plan to ship a new edition every December. When would we fork our internal spec to work on new features for the next edition while preparing to send the current edition to the General Assembly?

AWB: Every January

WH: Then we'd be editing two editions simultaneously almost all the time.

AWB: I can handle it.

WH: Yes, but can the reviewers of the spec handle it? We have enough trouble getting folks to re-read stuff as it is.

WH: Once every two years would be more reasonable.

Consensus/Resolution

5.10 Function parameter scoping and instantiation

Andreas Rossberg

[Slides](need to commit for a link)

Default Parameters/Arguments

Goals: Convenience Feature

  • Readable!

Non-goal: subtle expressiveness

Should be able to understand the defaults without looking at the function body

ARB: Two Issues

  • Scoping related to the function body

(examples of really weird cases)

Solution:

- Defaults should behave as if provided by wrapper function
-
-

Solution: - Evaluate defaults in seperate scope - Can see "this", "arguments" and function name (where applicable) - Can see other parameters - Cannot see bindings created in function body - Cannot see bindings created in function body LATER (via eval)

Evaluation Order

function f(x = y, y = 2) {}

function f(x = eval("y"), y = 2) {}

function f(x = (y = 3, 1), y = 2) {}

ARB: Preferably should be const bindings in that scope (not the funciton body)

AWB: (describes the TDZ)

Solution:

  • parameters have TDZ
  • Initialized in sequence

WH: No distinction between a missing parameter and explicit undefined?

AWB: We agreed on that a long time ago.

BE: I thought there was agreement/discussion?

(referring to: rwaldron/tc39-notes/blob/master/es6/2012-11/nov-29.md#proposal-part-2)

(need slide examples)

DH: Most concerned with implicit rebinding

STH: The rebinding is only observable

(discussion re: mutation in parameter bound closures)

STH: Can fix this while preserving

ARB: Can change the "nutshell" to meet the needs of the concern items:

const => let

BE: In the example that binds

AWB: - parameters are in separate scope contour - visible to the body scope - the body is disallowed from creating

- "namespace" for parameters

NM/RW: (agreeable points about curly brace boundaries reinforcing scope)

BE: Summary:

  • Outer Scope
  • Parameter Scope
  • Function Body Scope

YK: (recalling names declared in parameter scopes being rebound in the function body)

AWB: I can express this with one Environment Record

ARB: Cannot, because of eval. A delayed eval in the parameter list must not see bindings from the body


function g() {
    return 3 * 3;
}

function f(h = () => eval("g()")) {

function g() {
return 2 * 3;
}
h();
}

AWB: Agreed

DH: (post-clarification)

  • Two Scopes
  • The Function Head/parameter list
  • The Function Body

In the function head/parameter list, cannot see the scope to the right (the function body).

AWB: Any new syntax in the parameters, changes the handling?

(vast disagreement)

AWB: The spec currently says var-like bindings. If you have new syntax, they're still var-like

  • Duplicates are illegal
  • Rules about redeclaration
// If...

function f(x) {
var x;
}

// changes to...

function f(x = {}) {
var x;
}

// No difference.

// But changes to...

function f(x = {}) {
let x;
}

// Error for redeclaration.

(clarification re: nothing changes var bindings to let bindings)

WH: (whiteboard) What is the value of y in this example? 5 or 2?

function f( x=(y=3, 2), y ) {
    console.log( x, y );
}
f(undefined, 5);

(discussion without a clear resolution)

CF: What about:

var y = 2;

function f( x=y, y=3 ) {
    console.log( x, y );
}
f();

BE & Others: y is shadowed result is (undefined, 3)

WH: What is the value of y in this example? 2, undefined, or 5?

function f(x = (y = undefined, 7), y = 5) { ... }
f(undefined, 2);

AWB: The original value of the parameter is used to decide whether to default it or not. BE: Surprised. Unhappy with having to store the original values of the parameters, thereby making for two copies of each one. AWB: Already need to do this for the arguments object. BE: The arguments object is easy to statically detect. These are more insidious.

(no clear resolution)

ARB: Fundamendally these are mutually recursive bindings.

BE: We agreed on two scopes. Head and body.

  • If another parameter has a default?

Consensus/Resolution

  • Two Scopes
  • Head/Parameter List
  • Body
  • Temporal dead zone?
  • Details unresolved?

4.5 Modules Update

Dave Herman

[Slides](need to commit for a link)

Generic Bundling Slide

(Debate about hash as the delimiter. Agreement that this discussion can take place elsewhere.)

DH: the browser loader is not something that belongs in Ecma-262. It's a separate spec. We can do it concurrently. We definitely want to start now and get feedback early, but it doesn't need to block ES6.

(Discussion of confusion on parsing vs. evaluation timing. Custom loaders can implement the desired esoteric use case; see caching slides.)

DH/LH/JM: Use case under discussion is lazy module execution, like AMD bundles or previous named module declarations. If you have a console.log inside a module, is there a way for that not to get executed?

DH: we may need to check to ensure that is possible, but it probably is. And the simplification of removing named module declarations still seems worth it.

4.6 Unbound variable checking

Dave Herman

DH: Proposes that if m is an imported module, then m.bar should be a compile-time error if the module doesn't have a property named bar.

WH on whiteboard: Should this be a static error in that case?

module m from "foo";

with (a) {
    m.bar;
}

?: Modules are in strict mode and don't allow 'with'. WH: But this isn't a module; it's just referencing one.

Module loading

DH: it used to be that <script async> would be able to do I/O, including import declarations; I've relaxed that. Now <script> can do that.

DD/DH: (clarification that you can use module syntax in scripts, not just modules>

BE/DH: (discussion of allowing <script> without async to load modules.>

AR: note that inline scripts with async or defer attributes currently do not impact execution or parsing. This may change in the future.

JM: if people want to use import in a synchronous script definition, that should be OK; just throw

DH: that was the direction I was moving, but LH was objecting to. And DD has an interesting point that if we don't let import happen at the top level, that would work well too.

STH: What do we like?

YK: Adding a form to HTML that says "this is a module." This reduces the need to allow imports in scripts.

BE: that would mean we're betting on getting something into HTML

DH: yes, but you could just use the loader API.

BE (whiteboard): four cases

<script>(1)</script>

<script src="...">(2)</script>

<script async>(3)</script>

<script src="..." async>(4)</script>

WH: how do you load a module without async scripts?

YK/LH: System.load("module")

WH: and you wouldn't need to import System or similar

DH: no, that's just a global

WH: but we have features that require modules, e.g. iterator

DH/YK: yes, but you can just do System.get("std:iterator").iterator.

WH/DH: if it's hard to use a module inline in the page, then it's hard to write the good code we want them to write.

DH: this is something that needs to happen for multiple reasons, so it should happen in HTML.

YK: import in top-level scripts doesn't give us modules in top-level scripts, only import in top-level scripts.

JM: so how do you enter the module system from HTML?

DH: two ways. The loader API, or the hypothetical <module>.

BE (whiteboard); top level script looks like

let { keys, values } = System.get("@iter");

DH: BTW JS practictioners, I'd like to reiterate if you have concerns about the standard module system.

LH: Implementers will ship iterators before modules, so we need a way to get at these things more easily.

DD (jokingly): We can just use a proxy to trap @@iterator in the meantime.

DH: I really think this how-to-enter-the-system conversation can occur outside TC39.

BE: so we can provide two top-level environments.

BE: OK, this is all about separation of standards-body concerns.

DH: and this helps not block TC39.

(Discussion somehow turns back to <script> vs. <script async> getting

module-loading abilities.)

BE (to LH): so you're worried about an attractive nuisance, people doing more synchronous loading than they should

LH: Well today, import always succeeds, but with this proposal, it's order dependent, like today's System.get.

WH: <module> as a new HTML element won't work due to HTML parsing issues.

Note that scripts contain un-HTML-escaped <'s (and even larger chunks of HTML tags) while other HTML elements don't. An HTML parser wouldn't know how to properly skip past an element (such as the proposed <module>) that

it doesn't know about.

DH: I think <script type="module"> or similar is going to be necessary,

for many reasons.

DH: so to recap, there's the two possibilities: allow gradual integration via import etc. in scripts, or the green path where you enter the module system once and then are there.

JM: Facebook wants both, so we can do initial page load and async load.

DH: that's fine, you can do that with System.set in the initial page load.

DH/BE: (Agreement that this should go in other standards bodies.)

Back to Static Checking

LH: back to static checking?

BE: you have to do label checking. It's not that bad.

ARB/BE/DH: we have to implement to find out.

BE: how much parsing do you have to do?

ARB: so that's in the pre-parser for V8

BE/DH/ARB: (discussion of V8's pre-parser)

DH: somewhere in between a reader (along the lines of SweetJS) and a parser, and that's what I don't understand.

ARB: it's a parser, but it just glosses over a lot of the grammar.

ARB: to be completely honest, we would like to get rid of this thing.

BE: so we won't know if adding this static checking for modules has implementation consequences, until implementers actually go implement it. So if they have appetite for it, we should try to do that.

DH: JSHint or TypeScript could do all these things... We need to at the very least provide the basic foundation. But that would shut the door on further static things.

BE: V8, do you guys have an appetite for trying it?

ARB: I'd like to try, but not sure if it's possible within the ES6 time frame.

BE: and what about Chakra?

LH: we can try it, but we don't know...

DH: it would be OK with me to close the door on static things like guards.

BE (to ARB): wait I'm confused. If you're doing import/export checking, aren't you doing about the same work you'd be doing for full static variable checking?

ARB/LH: no

DH: import/export is top-level only; you don't have to walk the full AST

LH: you would have to freeze the global environment at the point in which the static checking happens, and test against that

DH: yes, that's right

BE: OK, so maybe it's enough to have import/export checking. That spot-in-time check could be a problem. Yes, this is a problem for monkey-patching.

DH: every time we go through these cases it takes hours to remember the global object semantics.

AWB: I thought we concluded a long time ago that we had to preserve global semantics.

DH: clarifies: only talking about within the body of a module.

  • Check the script against the current state of the Global object at compile time
  • This is an unsound and incomplete analysis, but, it's one that you can program to.

BE: so if we say that module bodies do not have this type of static name checking, we're closing the door to guards, hygenic macros, type checking, ...

WH: how does it close the door to guards?

DH: we always talk about guards as if we knew what their semantics were...

BE: OK, well, how about truly static stuff like types or macros.

DH: my experience in ES4 was that it was fighting with the dynamic aspect of the language

WH: in Lisp we have a multi-level time-of-execution (i.e. eval-when) system... it was very messy...

BE: I think static types and static metaprogramming as an option are shown to be not possible, really, via the fact that TypeScript and Dart are both basically WarnScript.

DH: I think that it's been shown that tooling is generally how the web solves this problem.

LH: and we could do this outside the language itself, the opt-in could be e.g. opening the debug tools instead of being in a module body.

STH: But, nobody's said that this is a horrible feature, there's just some implementer reluctance.

DH: JSHint works fine; modules alone will allow JSHint's undefined variable checking to work without having to provide a large list of globals.

LH: we've started creeping a little bit toward doing more static analysis, but this would be a big step.

DH: what do you mean static analysis.

LH: I mean more early errors. We added more in ES5, e.g. duplicate variables. ES6 has added more with let and const. This is the next big jump. It's not clear where that's trying to go... We could go much further, we could build the whole linter into that point.

DH: I have years of experience writing Racket code, which works exactly like this. Once you're in module code, you have static variable checking.

LH: but no global object in the scope chain.

DH: actually kind of, but yes, people don't use it nearly as much as on the web.

DH: The static variable checking is both unsound and incomplete; the former is because of snapshot-in-time globals, and the latter is because of the halting problem.

WH: I want a way to get static variable checking but also monkey patching. Perhaps declare which global bindings you might want to monkey-patch.

checks on import/export

# Rick Waldron (11 years ago)

# Sept 19 Meeting Notes

John Neumann (JN), Dave Herman (DH), Istvan Sebestyen (IS), Alex Russell (AR), Allen Wirfs-Brock (AWB), Erik Arvidsson (EA), Eric Ferraiuolo (EF), Doug Crockford (DC), Luke Hoban (LH), Anne van Kesteren (AVK), Brian Terlson (BT), Rick Waldron (RW), Waldemar Horwat (WH), Rafael Weinstein (RWS), Boris Zbarsky (BZ), Domenic Denicola (DD), Tim Disney (TD), Niko Matsakis (NM), Jeff Morrison (JM), Sebastian Markbage (SM), Oliver Hunt (OH), Sam Tobin-Hochstadt (STH), Dmitry Lomov (DL), Andreas Rossberg (ARB), Matt Sweeney (MS), Reid Burke (RB), Philippe Le Hégaret (PLH), Simon Kaegi (SK), Paul Leathers (PL), Corey Frang (CF), Mark Miller (MM)

(discussion re: destructuring concerns)

AWB: If you want to not throw for no value you have to define the default value.

DH: That's not YK's position. He wants to not throw.

DH/AR: The way you pull things out of an object is to do a [[Get]] wich does not throw and returns undefined

WH: What about {x} = undefined?

DH: That is not the same issue.

DH: In the case where the thing you are destructuring is an object, and the property you're looking for is not there, it should not throw. That matches existing JavaScript


{ a: { b: c } } = {};

The inner object is the source of the error.

ARB: Confused because notes different from what just said.

AWB: Currently spec throws unless a default value is provided.

YK/DH: Not happy with that outcome.

RW: (recalling agreement between AC/YK/RW at last meeting on feeling that we're not following expected JS behaviour)

DH: The obvious case is using an object.

  • What does the syntax most naturally correspond to?
  • Looking for smooth refactoring paths

ARB: I don't buy that it will be common to refactor like this

ARB: Common bug that you get undefined for o.x

DH: That is just how JS works and we cannot redo JS.

AWB: I can represent YK's position. Personally fine either way. But we need to decide. We cannot keep putting this off.

DH: I believe we would dissappoint the community if it threw. It is just too different from what they are used to.

AVK: My recolection was that we woudl go with no exception and maybe add a ! in the future.

LH: Ultimate consensus at last meeting was fail soft, waiting for ARB to object.

ARB: Other consistency arg with a future formal pattern matching

AWB: Yes, but for pattern matching we'd have something else

LH: If pattern matching used something else, and you were in that context, it's not a stretch to tell people there are new rules in that context.

ARB: Results in two semantics for one syntactic class (patterns). Bad for consistency and language economy

DH: Whatever familiarity from other languages and contexts, we need to align with JS and align with fail soft

AR: (to ARB) the practioners in the room are consistently disagreeing with your position.

RW: In a pattern matching context it is fine to do things more strict. People will not be surprised by the difference between destructuring and pattern matching

DD: (recalling recent extensive destructuring experience)

DH: Opposed to having two different semantics. Throw in destructuring but fail soft in [[Get]].

JB: What was the problem with ?

DH: Default behavior is backwards.

AWB: There plenty of unresolved syntactic and semantic issues and not enuogh time to get them done in ES6.

JB: and !?

AWB: No bang for ES6

RW: opposed to re-appropriation of !...

ARB: I think this makes for a worse and more error-prone language. But acknowledge that I am alone and I will not stand in the way of this.

Consensus/Resolution

  • Throw if not an object
  • Then do a (fail-soft) [[Get]].

9. Promises

Domenic Denicola

domenic/promises-unwrapping

DD: Consensus on AP3. Some issues with extending toward the future. Some bugs in the DOM spec. Tried to fix those.

MM: Recommending that TC39 adopt promises-unwrapping so that w3c can proceed, and TC39 also get consensus on adding .done, .flatMap, and .of.

AVK: promises-unwrapping is wanted for shipping in browsers. A lot of specs that rely on promises and we'd like a blessing.

  • AP3 was initial consensus
  • changes were made to make new consensus

MM: Can we agree on promises-unwrapping to move forward?

STH: The promises-unwrapping spec, in that it doesn't include ... (Google Hangouts misbehaves.)

MM: (explaining semantics and benefits of flatMap etc)

DD: without flatMap they will unwrap on the way out

STH: unwrapping?

DD: input side doesn't unwrap, only the output side

STH: Then I'm happy with this.

MM: No dissent from promises-unwrapping with the addition of .done, .flatMap, .of

WH: What is the unwrapping doing

DD/MM: explains that unwrapping occurs as long as there is a then() on down until there is no then()

ARB: (to Sam) I share the compositionality concerns. Are we sure there is compositional abstraction if you use two levels of abstraction?

STH: if you ever write .then, your system is not going to be compositional where promises are a data type (or you'll have to do extra work)

WH: What is a then-able promise?

DD/AVK: Just an object with a then function and you assimilate. It's "promise like".

WH: .then does what?

DD: .then is how you extract values

MM: (explains unwrapping again)

WH: What is .flatMap?

MM: A promise accepting another object, causes the .flatMap to

CF: it's "then" without magic

MM: it's lower level, .then is built on top of .flatMap

ARB: .flatMap is parametric and does no magic on it's values, where .then does

LH: the only way you can convert a thenable to a promise is return it from a promise. Promise.cast and Promise.resolve will not convert a thenable?

MM/DD: no, Promise.cast and Promise.resolve work the same way, storing any thenables as their value, and then the unwrapping happens when you call .then on the promise who has that stored as its value.

WH: What is "The ThenableCoercions Weak Map"

MM/DD: (explanations of security concerns)

  • No code contributed by the arbitrary object will execute during that call
  • assimilation of thenables was constructed so that the object cannot cause side effects during the operation

DD: It's clearer when the code intends to run async, vs. some code running when assimilation occurs and some code later.

MM: Then I should talk about .done now

AVK: I think we have consensus on promises-unwrapping, and can defer .done.

MM: declaring consensus now is crucial to unblock the DOM. If we can defer .done I am fine with that.

(General agreement that promises-unwrapping with .flatMap and .of has consensus and .done can be deferred.)

LH: Will need to add cancellation capabilities

  • Want to make sure that if we're sticking this in DOM apis, make sure there is back-compat safe to add them

AVK: I believe that Mark and Domenic have given plenty of thought here

DD: (confirms)

MM: Notes that test262 will need to be extended to support async testing

DH: This is really well developed and thoroughly spec'ed... what is the possibility of getting this into ES6?

(murmurs of insanity)

AWB: We're close approximate spec deltas here. Not quite cut and paste, but encourage that we might be able to fill in the editorial aspects.

  • What about the event loop interaction

MM: I think the right precedent is Object.observe, it was very well written, very complete and we adopted to ES7 (for as much as that means)

DH: Doesn't need to be tied to the event loop

  • event loop is very clear.
  • would love to recast the loader api in terms of promises.

MM: That's a better pay off

AR: Not quite that simple... in many cases result in void return types

AR/DH: agree that this is better overall

AWB: More confident about Promises, vs other features. If editorially practical, we should try.

AR/AWB: No syntax, so no issue there.

PLH: Makes life easier for w3c specs as well.

AWB: What about an ECMA technical report in the interim? Or an independant spec in the interim?

DH: In practical terms, that would mean I couldn't use them in the Loader api?

MM: w/r to synergy between module Loader and Promises

  • how much of a difference does it make, if you could rephrase the api in terms of promises?

STH: Many methods would change to use promises, a few cases would be drastically simpler, and all cases would be improvements in useability.

MM: I would be over-joyed to have this in ES6

DH: Most important to this: Domenic, Anne and whoever need to provide Allen with complete works as needed.

WH: Let's say we introduce structs where if you mis-define fields it throws?

DD: if you introduce changes like that, you'll have to re-factor checks throughout the spec and .then can be refactored in kind

DC: To be clear, a thenable is:

DD: An object that has a .then property whose value is a function (is callable)

WH/DC: ok

AWB: A bit of legacy around "callable"...

(Discussion about detecting then properties)

DD/MM: JSON.stringify precedent: determining whether to return a property based on whether it's callable

AWB: JSON.stringify is filtering...

DD: But same meaning

AWB: These callability tests are unnecessary?

DD: Proven to be necessary

WH: To avoid objects with .then that isn't callable... Why aren't we using [a well known symbol]?

AR/DH: There is no way we can introduce this feature that has a change like that.

  • A lot of existing code to interop with

DC: "then" is the wrong word.

MM: for a long time I fought for "when", but there is too much web-reality that calls it "then" and it wasn't worth fighting

WH: What happens if a thenable doesn't call onFulfilled or onRejected?

DD: then it stays forever pending. This is a valid use case, e.g. a server that never responds to a request.

DH: and it's actually a really nice zero of the promise algebra!

Consensus/Resolution

  • fast forwarding Promises into ES6 as per domenic/promises-unwrapping
  • Postpone with option of revisiting
  • cancellation mechanism
  • discussion of done method

7. Object.observe status report.

Rafael Weinstein Slides <--- etherpad fucks this up :(

Discussion related to how nested observers should chain.

AWB: Maybe have performChange do take one more parameter, that is the record a function that calls notify.

NM: Or have performChange return the record.

AVK: You can skip the object in the record because the notifier knows which object it is working with.

MM: Does not seem like a good path to not handle expecptions???

RWS: The mutation records from array methods are about the intent to mutate the object. It cannot tell what the new state is of the object.

MM: If somethings fails, and you try to perform the same operation on a replica you will get the same failure on the replica.

RWS: I attempted to do the work and this what I intended to do.

MM: I'm fine with this as long as it maintains the ability to keep a replica consistent.

AWB: Would it be ok to not record property changes on array propert changes.

RWS: If the array only said it was sorted then the code would need to keep a copy around to know what happened.

AVK: Is "sort" proposed.

EA: No

AWB: It is uncommon to care about property changes for lists.

AVK: <input type=file>.files might want to use Array.observe. It only cares

about the items in the array.

AWB: It seems strange to use observer for this use case.

DD: generally DOM has a lot of things where the only difference from normal ES constructs is that when the object changes, you need to update something on the user's screen. New subclasses seems unnecessary, there's no new API.

AVK: Considering using array or a small sub class. Reusing array as is easier because you get a lot of things for free.

AWB: Use more specific class than array.

(Discussion about Array.observe vs. Object.observe.)

RWS: Allen, I think what you're saying makes sense, and it's a specific instance of a more general thing of filtering, which we may want for performance. Let's defer that.

CF: An API question---what about { new: newCallback, updated: updateCallback, ... }, instead of (callback, ['new', 'updated', ...]).

DH: yes, callback-last is definitely important

RW: (explains in depth the benefits of this)

RWS: I'm not especially excited about separate callbacks, because often you want a stream of change records, and not to react individually to each of the operations.

RW clarifies with some code Corey's proposal:

// either

Object.observe(foo, {
  updated: function() {},
  deleted: function() {}
});

// or

Object.observe(foo, function() {});

RWS: This is an antipattern. We don't want to split the callback like that because the change log is the important part and if you split it it is hard to get ordering right.

RW: The misunderstanding: the list of change types is a "white list" of change types to include in the change list, not a 1-to-1 "events to handle" list.

WH: Want the names to be present tense, new, update, delete, prototype, reconfigure

RWS: prototype is used when [[Prototype]] is changed

WH: how often do you observe an object whose prototype chain changes

RWS: well, a common use case is using the prototype chain to represent concentric scopes, e.g. Angular

RW: It is valid to want to observe changes in the prototype chain, but I don't think Angular is a good supporting argument.

DD/RW: Object.setPrototypeOf is the supporting case for observing prototype replacement

DD: so then why not include observing the changing of extensibility

AR/AWB/RW: I think we need that for completeness anyway.

MM: yes, any mutable state should be observable; as long as it is observable by polling, Object.observe should work.

RW: agreed, you could definitely implement it.

Moved on to "Thought Experimental" slide.

WH/DD: the names on this slide are weird. "deleted" doesn't work (it's already used by normal objects). "set" vs. "updated". It seems like namespacing is necessary.

RWS: Agreed, there is a namespacing issue.

RW: Map and Set operations have potential to be deceptive; since the actual data is held internally, freeze operations have no effect (freeze is on the surface for tamper proofing), so there might be a situation where a Map or Set is "accidentally" assumed to be locked down but is still observable. FWIW, I do like the addition of change observation for Map and Set.

MM: Freeze is not about freezing the object, it is about making it tamper proof. I think we can postpone this to ES7.

RW: (to RWS) we can talk about this more offline

AVK: it would be nice if there was a recommendation for how to do namespacing, for other specs etc.

RWS: there is an unresolved issue about ordering of different types of work in microtasks (promises vs. MutationObservers vs. Object.observe); this is still undecided.

... Moved on to the performance slides.

RWS: the point of these graphs was not to show anything particularly interesting, but to show that there were no major surprises awaiting implementations.

AR: What do you need from this group? How close are we to being "done"?

RWS: Got good feedback on a few things to change. Maybe next meeting we'll have something that's really "done" and we can't go any further without implementations.

AVK/RW: just be sure to update us on es-discuss when you make changes.

Consensus/Resolution

  • failure cases, what to do when an exception happens midway through performChange
  • change type naming, eg. "sorted" => "sort"
  • 2nd/3rd argument order (offline discussion)
  • Post to es-discuss when wiki page is updated.

Licensing Concerns?

AWB: there was some discussion on the mailing list...

RW: I am pretty sure that was a troll.

STH: So this same guy actually came on the scheme mailing list and behaved similarly. It seems he just wanted to upload the PDFs somewhere, and did not actually care about the contents of the spec.

8. Data Parallelism

Dave Herman & Niko Matsakis

DH: I wanted to explain why the issue of sequential fallback is not as simple as "we should just throw" for synchronous code.

NM: I want to separate out throwing on non-parallelized execution vs. non-parallelizable execution. The former is not what people want.

(General agreement.)

DH: yes, you want the engine to be able to make dynamic decisions about whether parallelism is profitable.

NM: it turns out there are many reasons why an execution may be non-parallelizable, not all of which a user should concern themselves with. There are implementation constraints that make it very hard to parallelize in some cases, but in theory they should be parallelizable. For example, in SpiderMonkey, string operations: they are currently implemented in a very scary imperative way that is hard to make threadsafe, but from a high-level perspective it should be obviously parallelizable. (It's not mutating shared state.)

NM: Our conclusion was, we would instrument our JIT compiler to generate parallel-safe code, which needs a warmup; we'll run sequentially for a while, before we're ready to try parallel execution. It's going to be hard to implement a parellization strategy that doesn't work like this.

ARB: I totally agree.

DH: Cannot get to paralelizing until have done some serial exucution to gather information.

NM: Implementations will grow the set of code it can parallelize over time. Cannot force any constraints on the closure. The alternative would be to instrument the entire the engine ot keep track of what cannot be parallelized.

NM: The other option is to formalize what can be parelized in the spec. For the end user they will still not know what will run in parallel.

EA: What is preventing engines for running Array map/filter etc in paralel if it cannot be detected.

DH: It would be an interesting thing to try out.

NM: There are other methods like reduce that cannot be parallelized. We therefore still need the par* methods.

ARB: Throwing if it is not parallelized is not sensible because it is too hard to specify what things can be parallelized.

DH: The order is non deterministic. That is the big difference. And this makes it easier to parallelized.

NM: THe order is only crucial for reduce.

WH/NM: (discussion about definition of side effect, whether throw is a side effect.)

NM: 1) mutation of external state; throws; and straying into native code (that we don't have a safe version of).

LH: if I'm interpreting this correctly, it sounds like the whole parallel JS thing becomes less of a standards thing, and more of an implementation concern, except there will also be some non-deterministic parallelizable array method.

DH: but it's also important to give the parallelism recommendations teeth because then authors can depend on it.

NM: it's also useful to have a specification available for users to read to understand what works where. It doesn't effect the semantics, and it probably doesn't belong in ES spec, but it would be useful to have to point users to.

NM: for example we only lazily make function.arguments do crazy things, so that's not an easy thing to spec.

WH: do we really need new parallel/nondeterministic array methods?

NM: the main one is reduce. You can do a tree-reduction, but that is not always the right thing to do on all architectures; it has a performance cost.

DH: also, we want to have developer tools give feedback on what can be parallelized; we are talking with a PhD student about working on this.

ARB: How does this interact with GC?

NM: Works well using nurseries.

AWS: A version of region based collection.

Newly Added Global Object

DH: Straw proposal Symbol.iterator, Symbol.create

AWS: A single method on Symbol, Symbol.for('iterator')

EA: You can have get and set and use set to register user defined known symbols.

MM: registration needs to be like interning

DH: We're only talking about location of these new things.

EA: Libraries want to register well known symbols

DH: This is not what LH is trying to address

MM: Built-in symbols, as specified by the spec: no mutation and no global channel

Well-Known Symbols available on the Symbol object itself

LH:

  • well-known symbols
  • Symbol
  • Reflect
  • System

LH: We should be designing the library system independent of modules

DH: (clarifies) Implementation dependency graph, can't rely on these new objects without knowing where they come from (modules)

LH: We need to decide, concretely, if these are exposed on the Global Object.

(RW clarifies for MM)

MM: Will this break the web?

LH: Conflicts are soft conflicts because the objects are configurable

LH: How will symbols be held?

Symbol.iterator = @@iterator
Symbol.create = @@create

The value is the initial value (as done with other items in the spec)

writable: false configurable: true enumerable: ?

AWB: need to discuss @@toPrimitive

RW: Does this really need to be exposed?

AWB: It's useful for any objects that have iternal data (like Date)

Consensus/Resolution

Next Meeting:

Nov 19 - 21 at PayPal

# Brendan Eich (11 years ago)

Rick Waldron wrote:

  • Normalize CR, LF, and CRLF to LF [WH: Is this consensus recorded correctly? I understood the consensus to be normalizing all lexical grammar LineTerminatorSequences to LF.]

TC39 members (including me) tend to forget, or turn a blind eye, toward LINE_SEPARATOR and PARA_SEPARATOR :-P.

# Allen Wirfs-Brock (11 years ago)

On Sep 24, 2013, at 4:12 PM, Brendan Eich wrote:

Rick Waldron wrote:

  • Normalize CR, LF, and CRLF to LF [WH: Is this consensus recorded correctly? I understood the consensus to be normalizing all lexical grammar LineTerminatorSequences to LF.]

TC39 members (including me) tend to forget, or turn a blind eye, toward LINE_SEPARATOR and PARA_SEPARATOR :-P.

Does it make sense to also normalize other line separators to LF. Are there any known platforms that use anything other than CR, LF, CRLF as their default line separator? I tend to think that anybody who explicitly puts one of those other separators literally into a template string has a reason for doing so and we should just leave it alone.

# Waldemar Horwat (11 years ago)

On 09/24/2013 05:32 PM, Allen Wirfs-Brock wrote:

Does it make sense to also normalize other line separators to LF. Are there any known platforms that use anything other than CR, LF, CRLF as their default line separator? I tend to think that anybody who explicitly puts one of those other separators literally into a template string has a reason for doing so and we should just leave it alone.

I'm mainly wary of complicating things by adding yet another exception to a rule. Now we'd have two kinds of LineTerminatorSequences: ones that get normalized and ones that don't. This would make for yet another piece of esoteric trivia for users to remember or get surprised by if they missed it.

# Rick Waldron (11 years ago)

On Tue, Sep 24, 2013 at 7:12 PM, Brendan Eich <brendan at mozilla.com> wrote:

Rick Waldron wrote:

  • Normalize CR, LF, and CRLF to LF [WH: Is this consensus recorded correctly? I understood the consensus to be normalizing all lexical grammar LineTerminatorSequences to LF.]

TC39 members (including me) tend to forget, or turn a blind eye, toward LINE_SEPARATOR and PARA_SEPARATOR :-P.

Regardless, this consensus is correctly recorded (confirmed word-for-word). If we should address LINE_SEPARATOR and PARA_SEPARATOR as well, then it's an agenda item for the future.

# Anne van Kesteren (11 years ago)

On Tue, Sep 24, 2013 at 8:32 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

Does it make sense to also normalize other line separators to LF. Are there any known platforms that use anything other than CR, LF, CRLF as their default line separator? I tend to think that anybody who explicitly puts one of those other separators literally into a template string has a reason for doing so and we should just leave it alone.

Agreed. In addition to that, the agreed behavior is what text/plain, text/css, text/html, text/vtt, et al are doing and we explicitly discussed compatibility with that being desirable during the meeting. I don't see a need to revisit this.

# Brendan Eich (11 years ago)

We (TC39ers paying attention) can agree here too.

# Dmitry Lomov (11 years ago)

Pull request to clarify typed array extensibility consensus: rwaldron/tc39-notes#7

# Rick Waldron (11 years ago)

On Wed, Sep 25, 2013 at 4:46 AM, Dmitry Lomov <dslomov at chromium.org> wrote:

Pull request to clarify typed array extensibility consensus: rwaldron/tc39-notes#7

Thanks, I've landed this.

I've also re-submitted the Sept 2013 notes to Ecma.

# Waldemar Horwat (11 years ago)

On 09/24/2013 06:41 PM, Rick Waldron wrote:

Regardless, this consensus is correctly recorded (confirmed word-for-word). If we should address LINE_SEPARATOR and PARA_SEPARATOR as well, then it's an agenda item for the future.

Confirmed word-for-word with what? It's clear that we had different ideas about what the alleged consensus was. We agreed to normalize line terminators to LF. Nothing in the discussion led me to believe that we wouldn't be normalizing all line terminators.