July 27 2016 Meeting Notes

Rick Waldron waldron.rick at gmail.com
Fri Aug 5 17:16:40 UTC 2016

# July 27 2016 Meeting Notes

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

## 9.i.g Date.parse fallback semantics

Morgan Phillips


MP: (see link) Date.parse accepts strings that are implementation specific,
this is causing incompatibilities across runtimes with new and repeat bugs
filed regularly.

Suggesting: specify the _intersection_ of supported string formats, specify
this as the _fallback_ for Date.parse.


DE: How much which is currently allowed to parse is banned under this

AWB: In general, implementations are allowed to add extensions to do
something else rather than throwing whenever they want.

DE: If any impl. doesn't apply extensions to spec: what sort of strings
that currently parse, would _not_ parse (by only implementing this format)?

WH: (what are the data in results.csv?)

MP: Those are data generated by a fuzzer and the columns on the right are
"yes" or "no" whether the string parsed

WH: The table lists which dates are accepted, but what dates do they
generate? For a concrete example, line 30 is "may,may,-000000". It's
accepted, but what date does that produce?

MP: This will parse as May 1, 2000. Almost all of this is crazy, hacks on

(shock and awe)

SP: Web compatibility concerns?

MP: Working with V8 dev to add telemetry probes into V8 and SpiderMonkey.
The web is fairly broken already—implementing an _intersection_ as a
fallback should not break the web.

SP: Is the goal to find the intersection, or a refinement on the

MP: Refinement.

WH: Are there places where different impl. accept a string but generate
different dates?

MP: Possible, but haven't explored. So far have only looked for producing a

SP: Should that be included?


AWB: Can we replace "yes" and "no" in the table with the actual output?

MP: Yes

WH: Does the table include all "yes" rows (i.e. rows where the existing
implementations all accept the string)?

MP: removed, there are millions.

EFT: Those are covered by the proposed grammar

MP: In the table there's a column for whether the proposed grammar accepts
the string. It's the "parser" column.

WH: Row 4839 is accepted by three implementations but not the proposed

MF: There are 60 examples like that in the table.

MP: The grammar needs to accept more. The current grammar isn't what I want
to propose in the end.

AWB: I want to reference back to ES5 and when we added ISO dates and what
our thinking at that time was. What we did in ES5, we introduced the ISO
date format and we did a quick look at this sort of stuff, and decided it
was such an incredible mess that maybe there's no way to fix it. Part of
the thinking there was, do we fix up this thing that's here, and identify
which dates we take and which we don't take, or do we leave and assume that
some day in the future we'll introduce a new API that is a date parser, and
that we've designed from first principles of what dates we want to parse,
and we don't simply include funny weird cases that exist in
implementation-defined stuff simply because it's there. Because it's a new
API, we wouldn't have compatibility requirements. That's still possible--we
could try to find this intersection, or we could leave it alone and find
the date parser implementation that we want.

YK: [Agree, but Date API is generally the sort of thing that accepts junk
and is expected to do the right thing]

DE: Unfortunately, browsers don't have the luxury of doing what AWB
suggests, and the demands of web compatibility mean that we have to support
what other browsers support.

MP: noting reports that a company identified some large number of bugs
being date based.

DE: We have found that at least 4 out of 10k page loads uses the "legacy
date parser" in Chrome

#### Conclusion/Resolution

- Stage 1

## 9.iii.a System.global

Jordan Harband


JHD: We reached Stage 2 previously, and the remaining open question is
which name should be used. window would break lots of code, since everyone
assumes 'typeof window' indictates whether you're running in a main page.
The remaining options are self, global, and System.global

DD: there's also frames! (jokingly)

JHD: This is about breaking libraries like lodash, as well as breaking code
which runs in Node. self has for a long time indicated that your code is
used on the web, but it doesn't seem like a really big hazard; not much
code for that. Also, self is used to store the receiver, though you can use
arrow functions for most of those use cases these days. var self = this is
a frequent idiom. Ultimately, if we pick self, Node is broken.

DD: We (TC39) make breaking changes to Node all the time. I think "breaking
Node" is overstating it

JHD: This is a very common pattern, though it sometimes dispatches on
window or module.exports.

DD: We already have a lot of ways to refer to the global. Do we really need
another one? Further (lower priority), there is a distinction between the
global proxy and the global object. Setting properties on the global scope
sets it on the global object, but referring to it gets the global proxy.

(Discussing Domenic's concerns listed here:
https://github.com/tc39/proposal-global/issues/16#issuecomment-221558082 )

WH: How does this work across realms? The global object is a funny thing,
as depending on where you evaluate it from, you may get different ones. If
the global object is a proxy, is the system object also a proxy?

MM: The System object is very much like the Math object

WH: In an environment with multiple realms, there will be multiple System

DD: (draws diagram to explain WindowProxy)

AK: Is this relevant to the System.global discussion?

JHD: I'll reiterate that this is not adding a new capability, as you can
use the Function constructor; this just gives a way to do that without eval.

DD: Actually IE/Edge is restricted in a way that I don't understand for
calling the function constructor in some ways

MM: This is one case where it's been hard for me to contribute to the web
side of the standards world

BE: Ultimately this is about things like window.setTimeout (with a string
so it will do eval)? Or what situations?

DD: Even executing a closure.

DD: WindowProxy is there so that, if you navigate a frame within another
frame, the "window" object of that frame stays the same identity, so it is
a "proxy" to an inner global object which changes on navigation. There's no
way to access the inner object from within script.

JHD: Regardless of WindowProxy, System.global returns the global object,
the same one that's accessed through 'this' or whatever else.

DH: Yes, this is the thing in the space of globalness that's relevant.

JHD: So we need a way to access the global 'this' value, a way that's the
same across all environments. The function constructor can't be called from
CSP. So we have two options--the bare 'global', or System.global. I haven't
found anyone do typeof global

BF: Browserify's wrapper uses typeof global

JHD: But actually everyone uses 'typeof process' together with that when
detecting Node-ness.

AWB: Two other options for names: Object.global

MM: I veto that as it would violate authority separation. I want to
separate authority-carrying objects from non-autority-separating objects.

DD: But Object.__proto__ is Function, which gives you the authority to get
the global object anyway.

MM: Function and eval are evaluators; CSP gives you the option to turn off
evaluators. Any other environment such as SES/frozen realms has to
intervene in the evaluators in order to constrain the scope of the
evaluation. In any such environment, the function constructor has to be

YK: Doesn't that mean that we don't currently have authority separation,
and you already have to do some work for this?

MM: We've addressed current pain points; let's not add to the burden.

AWB: A lot of this seems to revolve around the function constructor.
Another place to hang this would be Function.global.

MM: Let's not spend time on things that are strictly worse

JHD: Mark has argued that this cannot be a global variable so that it's
more easily secured.

DH: Sounds like a good time to bring in the Realms API and the global scope
contour, which introduce additional concepts that want work in the
language. It's an open area for discussion, where we might want to expose
the actual current realm.

AK: There's something special about global. There's already three ways to
access this thing; adding new ways is sorta bad. We're not adding a bunch
of things; this is just accessing one thing.

MM: Right now, none of the ways of accessing global are not in the
ECMAScript spec, and it's a beautiful thing that the boundary between the
ES spec and the host corresponds very closely to user-mode computation and
system mode computation. ES standardizes no way to cause effects on the
outside world; the host provides bindings on the global object to cause
effects on the outside world. Because the other things are put on the
global, the global itself should be considered a host object that provides
access to these things. Because there is no binding to the global object,
nothing grants authority. There are several future proposals which do
things like that.

AK: We don't have any of those. Global is special. There is some advantage
to making the name short. Let's say it doesn't set a convention.

AWB: This should be a built-in module

JHD: So far, every time this came up, we said that we don't want to block
it on this; once there's a standard modules proposal, we can consider this.

DD: We have a strong precedent for just calling this global. I want to
understand your objection, Mark. It sounds like you're saying, let's not
set the precedent of exposing a power object, when it's already exposed in
reality in so many ways.

MM: Because it's not in scope in the ES spec, an environment could claim
conformance to ES without exposing this.

DE: It is in the intersection of the various popular embedding
environments, however.

JHD: I went with System.global because of the nonzero compat risk of bare
'global'. However, I haven't found any concrete compat risks. The second
reason is that Mark thought it would help restrict authority to put it
under a namespace.

YK: SES already has to care about this kind of thing.

MM: We currently have a whitelist in SES. global is not one of them.]

JHD: So if you're OK with not adding a global, you don't have to do
anything to SES?

MM: I'm concerned about the maintenance cost and initialization time. Spec
changes cause SES to trail, which users find painful.

JHD: But sounds like SES users will be protected anyway

AK: The difference between other things considered to add to System,
Loader, etc and global is that they add new capabilities, whereas global
does not add a new capability. It's just exposing an existing thing.
Therefore it doesn't need to be added in a particular namespace, and
doesn't set a precedent.

MM: I hope that frozen realms will be added and hide the global object.

JHD: It sounds like the requirement that it be under a namespace is not
very strong, simply a preference

MM: "simply a reference is too weak. The issue of distinctions and
psychological burden and precedent setting are pretty important.

DT: You're talking about the burden on developers?

JHD: I agree that they're real issues, but users already have the burden of
having this reference.

YK: Given that you expose the global object, seems like it doesn't give a
new capability.

MM: I'll have to think about this, but I can't approve that as a sound
choice at the moment.

JHD: If Mark were to agree to Yehuda's point, if we changed the name to
'global', would anyone object to it with the name simply 'global'?

DD: I'd prefer 'self'

CM: no self

DD: Would prefer `self`

AK: 'global' seems fine.  Most people don't seem to want 'self', Domenic.

YK, AK: This doesn't give any new capability as

JHD: Sounds like the next steps are for Mark to think through Yehuda's
objection and see if he can support bare 'global', and for me to follow up
with Mark, Dean and <who?>

#### Conclusion/Resolution

- Remain at Stage 2

## 10.ii.b Template literal revision to stage 3

Tim Disney


Reviewers: Mark Miller and Waldemar Horwat

TD: (recap) w/ tagged template literals, escape seq. illegal. Changes seek
to allow

- Only change:
removed the parametrization of the lexical grammar productions and instead
enforce early errors via static semantics attached to the syntactic
grammar. This change was result of Mark and Waldemar's review.

TD: Approval Stage 3?

#### Conclusion/Resolution

- Stage 3 approved

## 9.i.i ECMA402 formatToParts

Zibi Braniecki

ZB: Have implementation in SpiderMonkey, looking for a second implementor
to proceed stage.

DE: To help formatToParts to Stage 4, ideal to upstream to ICU

CP: upstreaming to ICU should not be a requirement

AK: V8 not waiting for Stage 4

YK: The chicken-egg problem is about unflagging, not implementing.

ZB: Hoping Chakra, JSC, or any would implement

DD: What is the rush?

ZB: Not a rush, but the proposal has been ready for half a year. This is
the last change that remodels the API. Everything else is new editions.
This change opens abilities for cleanup.

YK: My opinion is that we've met the criteria

AWB: Do we have two implementations?

ZB: Yes

AWB: Compatibility issues?

ZB: Shipped in SM behind flag

CP: There are alot of new Intl features that need formatToParts

DD: They can just be dependent

EFT/RW: That's bogus.

AWB: There is experience from significant usage? Want to hear about that

ZB: Used in consumer facing product, Panasonic TVs running FirefoxOS.
Proven that necessity to format is satisfied by this API.

AWB: With this exact proposal?

ZB: Yes


- Intl.js
- SpiderMonkey

ZB: The only feedback we've had is that developers want it in other

DE: Need to forward that feedback to other browser vendors

ZB: Want to plan for ES2017/402

RW: What is 262 cutoff?

BT/AWB: January/March (January for opt out, March for absolutely latest)

WH: I personally think you have enough implementation experience to advance
to stage 4 now.

ZB: Can we advance to stage 4?

AK/DE: Some cases need 2 or more browsers, but this is not one.

#### Conclusion/Resolution

- Stage 4 Approved
- https://github.com/tc39/test262/pull/734/files

## 9.i.j ECMA402 Intl.PluralRules

Zibi Braniecki

ZB: Can we advanced to stage 3?

ZB: Both reviewers (CP and DE) have finished the review!

CP: Thumbs up!

DE: The spec text is complete. No worries in terms of performance and
memory allocation.

ZB: All data needed for PluralRules to function are already in place, and
used by Number and Date, no extra data is needed.

#### Conclusion/Resolution

- Stage 3 Approved

## 10.i.a Require Unicode 9.0.0

Brian Terlson

[Patch: Require Unicode 9.0.0 instead of 8.0.0](

BT: We can update every year, or change language

EFT: "use latest"

AWB: Normatively referencing a spec with no version means "the latest"

BT: There are no changes in 9.0.0. Committed to reviewing changes each year.

RW: The 402 editor will have to do the same task


WH: New Unicode case mappings might cause `\p{}` (and especially `^\P{}`)
problems analogous to the `\W` problem we recently encountered.

BT: This won't be added in the future, but they can't be "fixed" because
they can't break compatibility.

DT: Should the requirements be clear for ES implementations?

BT: risk w/r to breaking change updating Unicode, larger possibility with
- Unicode is reluctant to touch case mapping
- characters might move

DE: But these tend to be bug fixes?

BT: Still a risk of a breaking change

#### Conclusion/Resolution

- Do not merge the PR
- Use language for "the latest" ie. unbounded reference
- This should be applied to 402 as well

## 10.ii.c trimStart/trimEnd

Sebastian Markbage

SM: change from "trimLeft" and "trimRight" to "trimStart" and "trimEnd".
Put an "alias" in Annex B?

SM: Web compatibility risk: the names of the functions changes.

DE: We changed a separately named Date method to an alias in V8 and didn't
experience any web compatibility concerns, so I wouldn't anticipate any web
compatibility issues here.

SM: We have other aliases in the spec; I was trying to follow existing

JHD: e.g., Array.prototype.values/[Symbol.iterator]

AWB: If there was evolution of mainstream functions, the web compatibility

DE: Code is likely not relying on the name, likely not much risk

SM: Need reviewers

Jordan Harband + Daniel Ehrenberg

AWB: Spec for trimLeft/Right is the same as trimStart/End?

JHD: Exactly the same, only a name change

MM: That's the breaking change?

JHD: Yes, otherwise there is no issue

#### Conclusion/Resolution

- Stage 2 Approved

## Array.prototype.values

Adam Klein

AK: We tried shipping Array.prototype.values and it broke some random
Microsoft property, with the "'values' in" pattern

BT: We shipped it

EF: We didn't ship it on Release, but it's on Beta.

AK: Safari shipped it, but it seems like people who depend on Chrome are
not shipping it. There's a switch between an object with a values property
and an array. This is a general problem with adding a property to existing

YK: We could add a function to get the values out.

AK: Chrome is not going to ship this any time soon, as we tried a year and
a half ago and it didn't work, and we tried now and it didn't work.

AWB: This isn't a web interoperability issue; it's a Chrome
interoperability issue.

AK: I'm not so concerned about it because it's not used so often, but it
might make people sad that it's not shipped.

AWB: This isn't a new thing in the world of JS, but eventually everyone
converges to standards, see IE/Edge

AK: Please do not add any more things to Array.prototype

BE: ES4 tried to do namespaces. Modules should give us a way to do this.
I'm agreeing, we can't really extend things too much.

RW: what software?

AK: CRM Dynamics 2013

BT: It is fixed, but people don't update their on-premises software. They
hire a contractor to install it, and then the contractor walks away. We
tell them just use IE11 rather than Edge.  You can configure a group policy
to open certain pages in IE11

#### Conclusion/Resolution

- No change; Firefox will proceed with caution in shipping values.

## 10.iv.a Class Field Initializers: this semantics

Jeff Morrison


JM: main issues

- Contextual things in the initializer scope.
- Initializers execute at the time of the last

- static field initializers are executed as the last step of class
definition evaluation, need access to the class name binding itself.

(discussion of the scope of initializers)

JM: What should be available inside the initializer?

- Banning arguments, new.target (b/c unclear) -- these are static semantics
errors when occurring literally, and `undefined` in direct eval
- Allowing this and super property access

YK: It would be confusing to have the old enclosing copies of new.target or
arguments inside of the initializers, which run later

AWB: Can't you write "arguments" in computed properties?

YK: We discussed this in the context of the cross-cutting class proposal
with Brian

- You might want this in a static property to refer to the class you just

JM: There have been issues created in the Babel tracker filed about the
scoping of this

AWB: In a static method this refers to the constructor function

- The constructor function that the static property is defined on

AWB: A consistency for static initializers for the left and right hand side
of initializers would be to be "the same as in a static body"

JM: open q: "Do we permit or ban new.target or arguments in the right hand
side of initializers?"

YK: This becomes tricky because some people expect that a field referecnes
ambient bindings, but it's easy to get confused if you treat the
initializer as a method

AWB: These initializers are very shorthand for a function, which always has

MM: In favor of banning

AWB: A usecase is a static method on subclasses that filters the
initializers, as called from a superclass constructor. In that case, you
want to call |new.target.initializerFilter()|, and so want new.target to

YK: Even though you can construct models which are consistent about which
is which with new.target and arguemtns, it's equally hard to construct one
that is unambiguously clear which one you are referring to

YK: This isn't a catchall; there will still be imperative cases that
benefit from being written in the constructor

JM: If we ban them now, we can always add them later.

JM: We also need to decide what to do with eval('new.target')

MM: Presumably if it's an early error without eval, then it will throw
early during the eval as well

(discussion of alternatives)

MM: Because this is a convenience tool, we can ban eval without loss of
expressiveness. It's just a loss of convenience

DH: On instinct, this scares me. Just because we can't come up with a
usecase, doesn't mean that something won't ever come up

WH: How deep would the direct eval ban go? Expression, subexpressions,
within arrow functions inside subexpressions, ...?

DH: banning direct eval is hard, because it's undecidable whether it's
direct eval

YK: Yeah, we'd have to ban the entire class of things that could wind up
being direct eval

MM; The only reason we're allowing these outside of the constructor at all,
is for common well-behaved cases

AWB: This of this as shorthand for function. If it was a function, all
functions define new.target. When invoked you get undefined. Functions have
arguments. There are no functions. If you just treat an initializer like an
anonymous function, then you get exactly everything falling out

DE: If you treat it like just a method, then you get everything you want

AWB: This avoids a laundry list of special cases

KG: What about statics? The easy corolary is that for statics, it's an
anonymous static method.

YK: This also allows for sane semantics for `this`

KG: (whiteboard)

class Base {
  prop = new.target.filter ? new.target.filter(val) : val;

class Derived extends Base {
  static filter() {}

AK: Does this restrict impl ablitie to optimize away? No, we should be able
to statically determine whether eval or arguments are possible.

EF: This is a simple front-end optimization.

Consensus: Initializers run with the semantics of individual anonymous
methods with no arguments being run on the class. That explains the scope
of this and super property access; new.target would be undefined, and each
would get a new empty arguments object.

JM: Do properties get created with DefinePropertyOrThrow() or Set()?

class FooText extends TextNode {
  textValue = "asdlsk";

YK: Users would likely expect to get a Set; most users don't understand
setters, and would expect that setters are always called

WH, MM: Would be really surprised by a Set in this example. The intuition
is for initializers to use define.

JM: You could phrase this either way; either it's a hazard, or it sets the
expectations that users can depend on a predictable DefinePropertyOrThrow.

WH: The reason why Set doesn't work is that it's not extensible to const,
to typed properties, all of these can only be done on DefinePropertyOrThrow

textValue = "adadad"

^^^ Authors don't immediately recognize that the difference between Set()
and DefinePropertyOrThrow()

WH: Can't use Set() to define const or typed properties. Only
DefinePropertyOrThrow will work.

MM: A frozen data property, overriding with Set() will throw

JM: Having spent some time on this, I think neither is more intuitive than
the other. People are very split on this. So as an argument for which is
more intuitive, that's a wishy argument. We should go based on what is more

AWB: If you define a method named textValue, you can't

BE: = looks like Set

AWB: So we should use colon

YK: Colon is reserved for type annotations

BE/WH: the only robust semantics is DefinePropertyOrThrow()

WH: Only DefinePropertyOrThrow will work across future extensions, for
const properties and typed properties

- evaluate the type, around time of initializer, can't create it and later
change type, so it MUST be created with DefinePropertyOrThrow()

SP: How is this conflated?

MM: The idea that an initializer does a Set(), but a const does a
DefinePropertyOrThrow() is just (confusing?)

MM: We already have in ES6 practice for how to initialize objects
imperatively, with `this.textValue = "asdf"` inside the constructor. That's
imperative, that does a Set(), it has all the properties that Yehuda is
advocating. Any proposal that adds new syntax should, to justify the cost
of the new syntax, it should have less overlap with something you can
easily say already.

this.textValue = "...";

...is a Set()

YK: This is shocking. That means that you are saying we shouldn't have

MM: I value symmetry, but I don't see a symmetry argument. Leaving aside
BE's point about the token, for object literals, all properties in object
literals are initialized with DefinePropertyOrThrow

YK: But most people will have the imperfect but good-enough mental model to
view this as a desugaring to this.textValue = ...

BE: This isn't true, as object literals already do something different
compared to manipulating the object, if you put a setter on Object.prototype

YK: But that is suprising to many useres

AK: What about developers of other languages who define fields and expect
those to not trigger setters (as in other languages, where setters don't
happen when you declare fields)

MM: This is just like an object literal. Writing object literals has the
same problem.

YK: That's different because object literals don't have superclasses.
People don't use __proto__: very much

BE: What's the robust, future-proof semantics? Seems like
DefinePropertyOrThrow, as Waldemar says.

DE: If you subclass an HTMLElement and try to define an onclick, that would
be fired either

JM: What about :=

SM: Having setters already be there is one use case. The primary use case
is turning an existing property into a setter or getter, to shadow
something else or make something lazy. If that's the upgrade path, then
this will break.

DD: That's a good point; people do deprecations by adding setters or
getters, and that would fail because it would just shadow

MM: If the semantics of this is Set, I would ask, what is the added value
of the proposal as a whole such that the proposal pulls its weight. You
could get these semantics just by writing the right lines in the

DE: Good from an optimizability stand point. We've been encouraging people
to be explicit about properties on `this` by adding them all in the
constructor, assigning `undefined` if necessary. This is a nice synaxt for

WH: Using Set() is dangerous, if derived class has foo, exposes you to a
super class that didn't have accessor foo, which is later added.

YK: Lots of classes which are designed to be subclassed assume that they
can intercept Set()s

DT: Initialization in C#, Java, etc is explicitly settting up the world and
invariants aren't there

DD: For us it's different, because super has already returned, etc

DT: Using DefinePropertyOrThrow is good because it'll give us that
capability from other languages, where you add the properties without
invoking setters.

SP: In the current proposal (with Set), it's the same as doing the code in
the constructor, so the constrained DSL is nice because it is not so
order-dependent, right?

JM: Sounds like we won't resolve the issue in this meeting; I'll work with
some people offline to come to more of a conclusion on this.

JM: The last open question: For fields that do not have an initializer,
these implicitly initialize to undefined, not copying this.x = this.x as
previously. I went back and forth on this; one of the reasons I was against
this is that I was concerned about shadowing the same-named property on the
parent class. But what convinced me is that, presumably, if you put that
declaration there without an initializer, you would intend to initialize it
later at some point, in which case you would be shadowing the parent
property anyway. So the expectation is that, when you put the field there,
you will be shadowing the field above it. So the initialization happening
in order makes sense.

class FooText extends TextNode {
  textValue; // textValue = undefined;

WH, AWB: Good.

AWB: In lexical scoping, we decided that the same name in the same scope
would always refer to the same binding. The analogue here points in this
direction as well.

JM: Cases where it's useful to define the value of a child in terms of the
parent property value...

this.x = this.x + 1;

AWB: Suggest creating the fields first, presumably undefined, then assign.

WH: Separating creation from initialization is not future compatible with
const or typed properties either unless we want to do something equivalent
of a TDZ for properties, which I don't.

WH: Back to JM's original question, the only sensible thing for a field
declaration without an initializer to do is to create the field with the
initial value undefined.

DD: left hand side of computed property evaluates once (for definition),
the right hand side many times (for instantiation)

[this.counter] = this.counter++;

JM: concern about syntax, further syntax might help solve, will consider


DD: It should be consistent with fields

JM: I see the analogy with methods as being stronger. Anyway, most use
cases will be with Symbols.

AWB: Want consistency across the whole construct, whether method, field or

AK: This isn't thought of as a statement, but rather as a declaration, so
the evaluation of the computed property names gods with the other

(discussion re: transpilers)

DH: "identifier : identifier" currently means type annotation

w/r to this ^^ https://tc39.github.io/ecma262/#sec-forbidden-extensions:

> The Syntactic Grammar must not be extended in any manner that allows the
token : to immediate follow source text that matches the BindingIdentifier
nonterminal symbol.

JHD: Babel is doing fine with Set, this scoping, etc, and we should take
that as a datapoint. No user complaints.

MM: Should the properties be defined as configurable or non-configurable?

JM: Currently it creates a non-configurable property with

YK: Seems strange why we would do it differently from methods

MM: I strongly prefer non-configurable. We already have an imperative
syntax for imperative initialization, properties that are configurable and
disappear. The time-dependent nature of configurable properties don't give
you as many guarantees. Non-configurable properties lets you minimize
gratuitious differences with private state and get static analyzability and
static shape. The behavior of private fields is more like a nonconfigurable
property than anything else.

AWB: I support your position, but in addition: one of the advantages of
this new syntax, is that it allows to declaratively define the shape of the
- Value in readability
- Make non-configurable is a powerful value

AWB: what happens when a super class has already defined one of these? When
they are configurable?

MM: Silent replacement
- Prefer: two declarations of the same own property, an error.
- Set() alone doesn't produce an error, DefinePropertyOrThrow() alone
doesn't produce an error.

DE: super constructor might return a Proxy

EFT/AK: Implementors can't infer more about shape than before

JM: Objections to Stage 2?

AWB: I want to see this and private fields merged. I don't think we should
advance either on their own to stage 3.

#### Conclusion/Resolution

- Initializers run with the semantics of individual anonymous methods with
no arguments being run on the class. That explains the scope of this and
super property access; new.target would be undefined, and each would get a
new empty arguments object.
- No consensus on Set() vs. DefinePropertyOrThrow()
- A field with no initializer should create the property with the value
- No consensus on configurable vs non-configurable
- Revisit initializer token choice of =
- Stage 2

## 10.iii.c [Nested import declaration](

Ben Newman

BN: Potentially relaxing restriction that `import` can only appear at the
top level.

BN: proposal would allow `import`s that are nestable; hoisted (declarative
over imperative); lexically scoped; sync evald; back compat.

BN: We have been shipping this to the Meteor community in a transpiler
context. The semantics are more subtle than you would expect to allow, due
to the subtleties of modules. They are synchronous (hoisted to the top of
the scope) and backwards compatible.

MM: [clarifying that bindings are immutable on the import side]

YK: [clarifying that currently proposal is transpiled to commonJS require]

… discussion about the spec; request to skip the spec discussion at this
stage …

AWB: How about we consider these to be ordinary lexically scoped variables?

WH: If I sit inside a loop, importing a module mutiple times, will I get
the same module namespace object?

BN: Yes. In subsequent iterations, it doesn't get imported again

WH: Is the module specifier still restricted to only being a string literal?

BN: Yes.

DH: in this proposal, no matter what, all imports will be loaded
beforehand. it's only that evaluation will be deferred until it reaches
that point in the code.

AWB: do you hoist evaluation as well as instantiation - i would expect that
hoisting for consistency with top-level imports

BN: the ability to have nested imports gives you a tool to control relative
execution of import declarations to other statements

WH: Yes, that's the Optimistic Imports example from the proposal.

YK: DH's point is important. If you want predictability, you do not want

BN: Modules get all loaded before the program starts. Their instantiations
are done as their blocks are encountered in the program.

WH: So then what happens if a module is missing when being loaded? How do
Optimistic Imports work?

BN: necessarily an error if it fails to load.

BN: … talking about a use case for cross-env code with conditional imports
… if it turns out that the fetching of the module source fails, it is
entirely conceivable that the dev knows this was a possibility and that
that import is inside a conditional block that prevents it from evaluating
- so i think it's less fatal for the fetch to fail.

YK: an important use case for this is "if i'm in env X, import stuff for
env X"

DH: proposal: we unconditionally do all the fetches, but if any fail, we
don't actually fail - just hang onto the error for later. and only if
control flow reaches the point where it's needed, does it end up being an
error. iow, if you only have conditional imports, failures will not create
a compile time error, and only create a runtime error when the module is
needed and missing.

AWB: consistent with the current spec.

AK: changing what used to be early errors into not-early errors.

AWB: i mean consistent in that it treats each block as if it's its own

YK: ?? conditional importing means the dev knows it's benign if it's
missing, and can work around that.

BN: … explaining "isolated scopes" example … ability to reuse identifiers
in the same file, but in separate scopes. With top-level, you need slight
identifier variations.

SP: also refactoring hazard - if the imports are in the describe, it's
easier to split up large files without breaking things.

BN: in top-level model you still have to do all the same fetching

CP: at what point in this program is the error triggered? we intentionally
chose declarative import evaluation as well as initialization/loading.

BN: the specific "it" test in my example will fail if the import nested
inside it fails to load.

BN: it should fail every time it's import is attempted

DH: it should be possible via the registry to clear things out and make it
possible to retry, but only in a staged way - ie, you have to kick off an
evaluation, not in the middle of a module.

BF: in node, if it evaluates, it's put into the cache; if it fails to
evaluate, it's not put into the cache.

… discussion about entire dep graph being resolved before any evaluation …

DT: … general argument that nested imports would have to be VERY compelling
to make it worth it …

AWB: what about imperatively using a dynamic import API?

DH: loader API does not let you statically express dependencies, so we
talked about a syntax that allows dynamic async importing

… more discussion ?? …

DH: inherent conflict with top-level await

BN: I think the dynamic syntax you're proposing is essential for top-level
await. what would happens with current `import` if you pull in a module
using top-level `await`?

CP: top-level `import` would handle it

DH: essentially forks the world - ie, "modules that can use top-level
await" and "modules that can't"

BN: still some motivating examples worth talking about

BF: a point: top-level await is going to pretty much wreck node's sync
loading anyways

BN: if top-level await turns out to be infeasible, then the conflict here
is moot, but still worth talking about

YK: my concern is that it makes loading unconditional + evaluating
conditional, and i think conditional loading is important too

BN: skipping over "lazy eval" claim. will note that in node, which has sync
i/o, pushing requires into functions has helped startup perf (likely from
deferring the i/o)

SP: depends on the complexity of the file you're importing

SM: biggest perf problem at FB is parsing and initialization. we load
everything and only evaluate the things we need. we can't switch to modules
without lazy eval + lazy loading.

BN: i think it will not interfere with lazy loading.

BN: if you treat all module identifiers the same, then you don't have to
parse the whole file, you just have to tokenize it and look for "import"

EF: i think you grossly underestimate the costs involved.

… discussion about tokenizing vs parsing; costs thereof; etc …

BN: in my naive understanding of tokenizing and parsing, you could
tokenize, iterate, locate `import`, locate the possible path - then
optimistically parse that path whether it's a module or not.

AK: unless you're talking about throwing away all module early errors, you
need to know the exports, so you still have to parse. your approach only
would allow easier fetching.

BN: if i'm wrong about the tokenizing trick, it still doesn't matter where
the import declarations are

YK: i think the point is that if it turns out that conditional import …

SM: what matters is "do you do the fetch if there's a syntax error"

CP: Do we need to have a user make a change to allow for this tokenizing

BN: The optimization is orthogonal

DH: He means deferring evaluation

BN: That seems unsafe to me.

BN: Colocating imports and code should be good long-term for code hygiene
because it should keep the things together and help you as you move the
code around. And of course you can keep putting them all at the top level
if you want.

BN: Further justification: Put an import in a try/catch block  in case you
have fallback behavior.

SP: But what if it's not the first time? This scares me. You don't get the
chance to execute your fallback behavior.

MM: Maybe you should remember the throw and rethrow if it failed.

CP: You were saying that it should go to the top

BN: To the top of the block. It will still throw from within the try block.

AK: To me, this looks like a nested module. It seems like it would be a
module in the tree which fails.

BN: Another benefit is dead code elimination--you can avoid running the
code by importing only when needed, and this then doesn't run the top-level

AK: Dead code elimination will be approximate in JavaScript. It couldn't be
done by implementations, but could be done by preprocessors which are OK
with changing semantics.

MM: Is it valid to eliminate the fetch?

BN: Technically these change semantics, but may be OK for the application.

BF: Module resolution may not include fetch; for Node, things will be

YK: We did a lot to support the web's asynchronous fetching.

BN: Yes, we needed to support browsers. Nested import declarations seem
problematic mostly because of the browser and asynchronous fetch.

BN: I have a grammar in the proposal. Import is not allowed in non-modules.
There is a PR, I invite people to participate there. Nested imports from
scripts are prohibited with static semantics.

BN: We have settled on declarative imports, hoisting them.  But nested
imports give you a tool for doing imperative imports, though no deferred
fetching and specifiers are literal

BN: Stage 1?

DH: Suggested area of exploration: await import
async fn() {
    await import {x} from m;

AWB, YK: We should merge this group with the loader group to come back in a
few moths.

AK: I'm surprised you're not upset about it being a promise.

DH: But the Promise is not reified

BN: I would prefer synchronous semantics, if possible, but we could live
with this. For one, it would be nice to run successive import lines in

#### Conclusion/Resolution

- Does not reach Stage 1; a synthesis proposal will be pursued at a future
meeting. Remains at Stage 0.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160805/0e6537b6/attachment-0001.html>

More information about the es-discuss mailing list