September 2015 TC39 Meeting Notes

Rick Waldron waldron.rick at
Tue Oct 6 18:49:02 UTC 2015

# Sept 22 2015 Meeting Notes

Allen Wirfs-Brock (AWB), Sebastian Markbage (SM), Jafar Husain (JH), Eric
Farriauolo (EF), Caridy Patino (CP), Mark Miller (MM), Adam Klein (AK),
Michael Ficarra (MF), Peter Jensen (PJ), Domenic Denicola (DD), Jordan
Harband (JHD), Chip Morningstar (CM), Brian Terlson (BT), John Neumann
 (JN), Dave Herman (DH), Brendan Eich (BE), Rick Waldron (RW), Yehuda Katz
(YK), Jeff Morrison (JM), Lee Byron (LB), Daniel Ehrenberg (DE), Ben Smith
(BS), Lars Hansen (LH), Nagy Hostafa (NH), Michael Saboff (MS), John
Buchanan (JB), Gorkem Yakin (GY), Stefan Penner (SP)

On the phone: Mark Miller (MM), Dan Gohmann (DG), John McCutchan (JMC)

(Need attendance list)

## 1. Opening Items

JN: (Introduction)

JN: Agenda is

YK: Post ES6, do we want to break up days into plenary and presentation.

AWB: An agenda item?

BE/YK: Add to agenda


- morning plenary groups
- afternoon discussion

LS: (facilities)

## Adoption of Agenda

AWB: Future agendas should avoid being specific about the version

BE: Helpful for me to know which features are on track

#### Conclusion/Resolution

- Change agenda "Proposal for future editions of ECMA-262"
- Agenda approved

## 4. Secretariat Report

JN: 1 o'clock on Thursday

## 5.1 Shared memory and atomics

(Lars T Hansen, Mozilla)

Need slides

LH: Work in progress at Mozilla, Google, etc.

Use Cases


- pthreads in translated C/C++ code
- Support for safe threaded languages

"Plain" ES
- Shareed state and multicore computation
- Fast communcation through shared memory

Use cases conflict:

- asm.js has flat memory, no gc, string types
- plain ES is object based GC'd weak types




Provide low-level facilities
- SharedArrayBuffer + TypedArray
- Atomic Operations
- Concurrent agents (introducing)
- Agent sleep/wakeup operations

Build Higher Level facilities

- Locals
(need slides)

API: Shared Memory

A new data type:

var sab = new SharedArrayBuffer(size);
(need slides)

Views on Shared Memory

var sab = new SharedArrayBuffer(size);
var ia = new Int32Array(sab);
var fa = new Float64Array(sab, 8, 10);

(need slides)

API: Atomic Operations


API: Agent Sleep and Wakeup

Modeled on the Linux "futex" (fast user space mutex)

Atomics.futexWait(i32c, loc, expect, timeout);
Atomics.futexWake(i32c, loc, expect, timeout);

- Minimal assumptions, very flexible
(need slides)

Example: mutex lock()

//  get code from slide

Discussion re: scheduling and execution.

DH: tasks can be scheduled, but not executed

CM: Understanding there would never be shared state threads in JS. This
appears to be that.

(Discuss after presentation, Moving on)


Agent Model

- Need a model for concurrency in ES
- Define concurrency in termsn of agents
- Define agents in terms of ES6 jobs
- Give jobs a forward progress guarantee

Agent Mapping

- In a browser, an agent could be a web worker
- SAB sharing is by postMessage,
- WebWorker semantics need work, nearly useless today.

- In a non-browser setting (SpiderMonkey shell)
- concurrent thread, separate global environment
- mailbox mechanism for sharing memory

AWB: Can imagine request for generalized model

DD: A different group could approach to define generic

AWB: Dont want a mechanism that will only work in a browser.

LH: (Confirms)

Implementation Concerns

- Trick to block on the main thread in browsers?
- Subcontracting, main browser thread actus on behalf of worker
- Possible to deadlock if main thread is waiting
- Make workers not truly concurrent
- Where's the bug?
- Subcontracting for UI and other things are also problematic

DD: An early version of this proposal said that these APIs were not on the
main thread

YK: Scary to have locks on the main thread

LH: Not that scary, it's no different than a loop

YK: Async functions are the solution that has evolved

AWB: Are the workers multiplexed?

LH: If JS on main thread creates a worker and waits on the location, it
will hang because the worker doesnt get started.

AWB: Semantically observable?

LH: Can observe remotely (a corner case)

Memory Model (1)

- Atomics in the program are totally oridered
- Conventional "happens-before" relation on events:
- Program order (intra-agent)
- Atomic-write, atomic-read (intra-agent)
- futexWake called -> futexWait returns (intra-agent)
- postMessage -> event callback (intra-agent)
- transitivity, irreflexivity

Discussion: clarification of consistency model

Memory Model (2)

- Reads only see writes that happen before them (and only the last of those
- Unordered accesses where at least one...
(need slides)

Memory Model (3)

- Races are safe, programs don't blow up
- Races are unpredictable, a race poisons the memory by writing garbage
- A race affacts... (need slides)

DH: Say there is a non deterministic collection of memory bits in location

YK: What happens when you read the garbage?

LH: Currently will get the garbage

Memory Model (4)


- Aliased arrays and cells thar are not exclusively atomic
- Weakly ordered memory (ARM, MIPS, Power)

C11, C++11 have similar issues, mildly unsound?

Java Better? But complex and subtle

DH: if mem model says data structure, behavior localized to data structure.
integration with rest of language impacts jit compilers, spec semantics
(how deep). Not sure what the biggest risk is... limited to array buffer
and only in specific case? Invariants in loads and stores

LH: optimization to load value from typed array, use it for something, eg.
function call. If not affected, can reload.

DH: Already know typed array, can assume not shared array buffer. Cases
where I _don't_ know the backing store, nervous

AWB: Typed array accesses with brackets

Limit concerns to optimizations re: Typed Array cases.

DH: Concerns: How much does this leap into the current spec. How much does
it affect the lower level operations?

AWB: Typed Array access get turned into operations on their bufffer. Buffer
operations become polymorphic (unshared, shared). A common operation that
occurs, with slightly different behavior.

Other Memory Model Issues

- No "relaxed" atomics, we problam ant them but they are complicated
- No "acquire-release" atomics, ditto though weaker use case
- Shared memory can be used to implement high-precision timers (you just
count), which can be used to simplif cache sniffing attacks
- Slight security concern
- Misc minor issues, see github repo

BE: Like mips load, link (re: "acquire-release")

LH: (state of "acquire-release" on current platforms)


- Spec is stable, memory model is being refined
- Firefox Nightly since Q1 2015, demo level code for asm.js, plain JS is
- Google have committed publicaly, at least in part
(need slides)

CM: This is terrifying. Can see cases for use in libraries for
communicating internally, but as soon as this is exposed to random web
developers... The nightmare is people that don't know how to code in this
paradigm. Likely a majority. Now can write highly insecure programs,
introducing the problems that JS rid us of

YK: What about other high level languages, Ruby? It exposes pthreads. Then
developers write better higher level abstractions

CM: Nothing to protect from authors of page and script running in it.

YK: Concerns is third party scripts?

CM: Yes.

YK: Could mitigate

DD: sandbox?

CM: Could design the things you might make with this, then codify into

YK: Verification?

CM: No, if the facilities don't exist, then safe.

BE: Agree, most web developers should not be tempted, even able to write
shared memory programs. We need to talk about what goes wrong. Cannot have
shared memory without races? We have demand for this.

Why Not Just for asm.js?

- Some tasks are best/only done in JS callouts
- I/O
- Thread Management
- Runtime tasks in general

- JS has data structures, easier to program
- The callout needs at least some shmem access

LH: need to satisfy both use cases

DE: Any program can already get into an infinite loop, unresponsive.


BE: If we don't do something like this, there will be a bigger gap for
webassembly stuff.

YK: Shared memory is not inherently unsafe, only in raw form. We can
provide safe access.

(Mark joins on phone)

YK: Need to more concretely address the constraints

MM: Will read emails from waldemar:

- Introducing a high bandwidth side-channel
- Even if only computation with coarse granularity, the ability to access
shared memory seems fatal.

LH: Only fatal if you can prove it's not already possible

MM: No way to do high-bandwidth side channels, such as cache attacks

MM: Timing attack is: shared array buffer with self.

BS: Issue is using the shared array buffer as a timer, you just read it and
allows cache attacks

MM: If attacker can create two threads that can communicate, you can create
high resolution timer attacks

BE: There's been demonstrations of not-as-high resolution timer attacks
that already exist. This is not the _first_ high resolution timer attack.

MM: Waldemar believes this is a bad vulnerability


DE: Any further conserns?

MM: Delayed weak refs because of

- JS has become mostly deterministic
- Plat

- bits in nan are platform dependency, not generatl non-determinism
- for-in iteration order is platform dependency, not generatl

MM: On whatwg, proposed System object. System is not distinct from the ES
built-ins. Grants

MM: perhaps the non-determinism comes from creating the Worker in the first
place? Thinking out loud

Where does one get access to the SharedArrayBuffer constructor

Either from global or imported from module.

AWB: How do you gain access to an already existing SAB created in another

MM: Creating an SAB alone is safe.

BE: The


LH: the resolution of has been reduced to help prevent the
caching attack

DD: not concerned about the paternalistic argument, rather the actual
security concerns?

YK/CM: Concerned about the programmer shooting themselves in the foot

MM: Concerned about security attack, more than programmer

CM: concerned about DOS attacks from third parties
...concerns are directly related

YK: Right way: expose async futexWait

LH: Originally had an async futexWait

CM: Proposing non-blocking-but-blocking?

YK: No, want to express sequencing in a local way. This will be done with
async function
... want same solution, async futexWait

MM: Q: motivation for SAB proposal: conventional c/c++ pthreads code can be
compiled through asm.js can still fnction?

LH: That's one of the case

YK: Shared Memory is a useful primitive.

MM: Want to separate:

1. Compile old legacy pthread code
2. Make good use of hardware parallelism

BE: legacy?

DH: Tried to build higher level primitives to give deterministic
parallelusm to JS. Challenging. Meanwhile the extensible web strategy
proves every time. Expose better, high performance, multi-core parallelism

YK: Should give 0.01% more credit (like authors of gzip, etc)

LH: first thing I did when I finished the prototype

MM: fan of the Rust/Pony approach, low-level, universal. Arrived
independently at a similar result.

YK: Easily imagine a Rust-like model, b/w dynamic checks

DH: Rust has Shared Memory concurrency, static type system and library
design that statically guarantees of performance and programming model. Can't be added directly to
JS, maybe with APIs and DSLs that have some speed tradeoffs, don't know
what will win in the end

BE: MM mentioned Pony, which has similar design

BE/DH: Cannot evolve JS into Rust.

MM: not what I'm proposing. I'm proposing investigating building on
TypedArray safely parallel memory system with ownership transfer of region,
capitalizing on Rust/Pony development

DE: how do we solve the compile from C++ problem?

BE: circles back to earlier point: don't have time to find SAB
alternatives, without exposing shared memory needs of C++. If we do
nothing, then other "bad stuff" will happen. If we do this, then other
people can experiment to find a better solution

MM: The potential show stopper: the side channel. I want to see some real
analysis of this danger and why we should be confident that the danger is
minimal, before we proceed.

LH: we have security people working on that, we can try to expedite.
- danger is that page load, you think its safe. Allows to fork off a worker
with shared memory, and there's the attack.

YK: Might want restrictions on the main thread, so ads can't own your site

LH: is this appropriate for the language or the browser embedding?

LH: whole thing with service workers/shared workers is tricky.

YK: Thing is (oksoclap disconnected on me, notes lost)

LH: fundamental constraints with blocking on the main thread? Or can the
browser implementations work around this.

YK: is this a fundamental C++ problem?
- fetch in browser: fork off a thread, do the work, wait for response.

LH: depends on which web APIs are avai
- want to update webgl

"shared" or "transferrable" canvas

DH: Concern, if growing API, implementation burden to find ways to share
with workers? maybe WebIDL?

AK: More clarification on urgency?

BE: if we do nothing, it is a bigger jump to WebAssembly, or somebody else
will do it anway to compete. Can't polyfill Unreal engine 4.

DH: Jeopardize adoption of web assembly.

AK: Is this going to be a problem with wasm features for time to come?

BE: maybe in the future JS will not be serving the cross-compilation
master, but not right now

YK: constraingts: what dynamic checks do you need to make SAB work?

BE: if we have web assembly in all the browsers, why would we need these in

MM: Memory model discussion?

LH: we talked about that.

BE: If we say out of bounds "no and forever", something else will happen
(see: flash, java). We need to work towards something.

YK: concrete example: VLC in the browser, don't want to write C, write JS,
chunk up the screen

AK: Can't use argument of "needs" c/c++ pthreads.

LH: (pre lunch summary)

- This feature has cost
- sophisticated shared memory given to those that don't know how to use it

YK: better to allow the ecosystem to help us design the higher level sync
operations than try to design ourselves

LH/MM: discussion of burden of proof of timing channel attacks

BE: hard to choose between higher-level and lower-level primitives

YK: quarantining helps that problem. Have to deal with timing channel

CM: not sure quarantining is sufficient, what are the modes of
vulnerability. Ecosystem of mutually distrustful components, run the risk
of someone not paying attention, leaving the barn doors open

YK: orthogonal to the primitive, access to the primitive

AK: depends on the primitive

YK: actually, yeah.


BT: True that impl. shared array buffers in wasm is easier than normal JS?

LH: Different, not easy
...Optimizing generics atomics, backend implementation

BT: SAB in wasm have same security concerns?

LH: Yes.

BT: Need a sense, wasm is a ways out.

BE: something will happen if we don't act

LH: thought about having it only in asm.js, not sufficient. runtime and IO
services need accesses to shared memory and atomics. some of it could be
moved into asm.js, but not all of it. to do so asm.js would need access to

DH: Value? Same potential security concerns. Same access from JS. Also
brought in requirement to standard another thing. If done in asm, then need
to standardize all of asm.

BT: what about WebAsm only? I don't think polyfills are critical. asm.js is
great because it is a subset, sound great as a marketing story, but haven't
seen a real example

DH: Important that it was a subset, was adopted.

BT: asm.js compiled stuff doesn't work when asm.js is turned off. Games
will not run in wasm

YK: gzip.js?

BE: you're saying that things don't work well outside of optimized asm.js?

BT: wasm polyfill has no value to game developers. Unreal Engine running
against this polyfill will not work.

DH: asm.js exists today! Polyfill WebAssembly to asm.js, it will run well.

BT: asm.js apps running without asm, don't run.

DH: two different stories: asm.js as a subset of JS is to break out of a
deadlock. Disagreement between browsers about how to port C++ apps to the
web. Competitive pressure created excitement. Kickstarting the process.

BE: (shows zombie chicken killing example in browser) compiled to asm.js,
running in browser.
(He's playing this next to me and I'm really more interested in that than
the current discussion. - RW)

DH: WebAssembly is in a different place -- not about disagreement between
browser vendors, there is agreement. The polyfill here is about making sure
that browsers that haven't yet implemented features can still run, and
people can ship functionality.

BT: wasm polyfilled ontop of asm will be a useable experience?

BE: Yes, I'm playing right now.

BT: the polyfill burden for asm.js is too much, you can probably get better
performance without asm.js. Kind of a side tangent

DH: this is super important! Need to keep our eye on the ball for polyfill
for WebAssembly. Still have a couple of years before wasm, maybe more years
before all browsers have the functionality, maybe timeline is off, but the
polyfill story helps mitigate the risk of shipping wasm features.

BT: if I'm Epic, I need two codebases to support asm.js and non-asm.js

YK: long tail of things that benefit from asm.js, but still work without

BE: spoke with Apple about this, they think they don't need to specialize
for asm.js, can generate good code without detecting "use asm"

BT: Why polyfill?

BE: Can run code sooner than later.

BT: Browsers that don't support asm or wasm will be gone soon?

BE: That support asm, but don't support wasm.


BT: I think I can understand the value of the polyfill

BE: But do we want to add it to JavaScript for all time? Maybe that's not
the right argument, what about Rust to JS, Pony to JS, etc.

BT: But you can still do that from wasm, right?

LH: we need to make sure we support both use cases, compile to asm.js and
data parallel in JS. Much more useful to have both than not

BT: I agree we shouldn't be telling JavaScript devs that they can't use
these features, but do we save anything but focusing only on asm.js? It
sounds like no

LH: I don't think the extra burden to the JS dev is very big

AWB: It doesn't seem like it would be optimized very well if we force JS
devs to communicate through asm.js for this feature

BT: If there is strong motivation to add for all time, then I'm fine. As
long as not _just_ for a polyfill.

DH: I see this as a building block for the long term

BE: we need to reach consensus, but we don't have to say this is going to
be in JS forever just yet

LH: Request Stage 1, with a list of things to investigate.

MM: w/r to SAB, discussed extensively that burden of proof to show cache
sniffing vulnerability is on the champion

... memory model is not contained. This will bleed into anything that
touches the SAB. We need to try to find a way to contain it.

LH: sounds reasonable

AWB: Object to Stage 1?

MM: no problem moving to stage 1

YK/SM: What restrictions do we want, who do they work? Difference between
global and local.

CM: All concerns are stated.

#### Conclusion/Resolution

The committee agrees that those wishing to advance shared array buffers
must explicitly address the following before further advance is considered:

1. To what degree might shared array buffers exacerbate the side channel
problem that web browsers suffer from?
- The issue is the potential increase in vulnerability over the status quo.
- How bad might this new side channel be?
- How can we be confident that it is not worse than that?
- How bad is the status quo?
- How much less bad could the status quo implementation be without breaking
the web?


[Waldemar: I couldn't attend the meeting because of an injury accident but
was asked to share my concerns about how bad this can be. Here's a paper
demonstrating how one AWS virtual machine has been able to practically
break 2048-bit RSA by snooping into a different virtual machine using the
same kind of shared cache timing attack. These were both running on
unmodified public AWS, and much of the challenge was figuring out when the
attacker was co-located with the victim since AWS runs a lot of other
users' stuff. This attack would be far easier in shared-memory ECMAScript,
where you have a much better idea of what else is running on the browser
and the machine (at least in part because you can trigger it via other
APIs). ]

2. To what degree can normal JavaScript code be insulated from the
complexity of modern memory models?
- For code that does not itself touch a shared array buffer, but for
example, merely calls something that does, it is not reasonable to disrupt
the programmer's understanding of the JavaScript program in terms of naive
sequential consistency.
- Of course, one can do that at the price of fine-grain synchronization
and/or avoiding all interesting compiler reordering like common
subexpression elimination. But such approaches are likely to kill the
performance that motivates this proposal in the first place.

## 5.2 SIMD.js Stage 3 proposal

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

DE: (update)

(Copy from slide)

AWB: do you mean they are not canonicalized in a SIMD.js operation or when
you extract? lumping load/store w/ extracting

DE: canonicalized at extraction
- Interfacing between SIMD and TypedArrays, never creating a JS scalar

AWB: don't think you need to say this

DE: consensus among implementors was to specify.

AWB: I don't think this is observable. It is no more observable than normal
number arithmetic, you can tell with two values but not necessarily that a
third is the same

DE: change makes spec more strict.

DH: observable.

AWB: TypedArray, have a signaling NaN. SIMD signals on signalling NaN, if
the SIMD unit processes, you must get exception thrown.

DE: Yes, I think that's what should happen, but we also removed the feature
in another case. It's not really in use

AWB: Read from TypedArray a f64, allow that to continue being a signalling

DE: We were trying to make the change on the writing side, but we changed
to not care about that

AWB: concern that implementation will have to change to allow for
signalling NaN. Saying that the implementation cannot change that to a
non-signalling NaN.

AWB: Do any known implementations treat signaling as non-signaling?

PJ: x86 doesn't, it just uses the default control register

DE: We don't allow people to turn that on from JS anyway

DE: Suggested to make lane an argument to load/store

BE: case wants constant. (lane argument)

(Copy from slide "changes")

DH: (question about partial staging?)

BE: Seems better than going back to zero

DE: Diff in how hardware works, between ARM and x86. Proposal to have
opaque type for this case

BE: Don't know how to fix this without support from hardware?

DG: We have a proposal that works, but we don't have enough confidence.
Current proposal doesn't use an intermediate type

(Copy from slide "questiosn raised by reviewers")

- SIMD as a built in module (now, global object)?
- Methods on wrappers (now, static functions)?
- Class hierarchy to reduce duplication?
- Equality semantics?
- Motivation for certain operations?

DH: agree, modules should not be a blocking depedency

AWB: Possible to define as module, but also not be a blocking dependency
...Issue is the _size_ (500 intrinsics) relative to the actual use.

DE: down to 300 now, signed vs. unsigned added an additional 100 or so

AWB: Didn't have to.

DE: targeting asm style compilers and normal JS JITs

AWB: One possibility: build heirarchy. eg. All the integer types can share
an add method. You need to check the arguments anyway.

BE: this is class-side inheritance

AWB: confirmed.
...Type check -> type dispatch.
...add method can check type of value

BE: you're saying that implementations need to optimize down to functions
with typed arguments

Discussion re: overall design.

AWB: remaining concern: huge API surface area

DE: Still don't think it's a major concern.



Could be:


Because type check must be done _anyway_.

JMC: Doing that loses the static knowability

DE: Big difference between optimizing for a completely unknown case and
just deoptimizing for disallowed types.

JMC: in terms of RTTI you don't lose anything, but in static case you do

static types give us hints, otherwise we...

AWB: a hint is just a hint, still have to handle the general case

DE: we can propagate the type infomration in asm.js

AWB: this is a general type inference propagation problem

BE: Full JITs do that, but asm.js doesn't. This is not a simple API

DE: Not usable by people who don't know what type they're working with
ahead of time

BE: SIMD programmers must now the exact types, they'll write by hand.
Nobody is calling for the frombits case except you (AWB). JMC, do you agree?

JMC: people will write this code by hand. people know the types, every SIMD
program is completely typed. Nobody cares for a generic conversion, they
know the types, it's been propagated the whole way through

AWB: That's generally true for most code that people write in most
application domains. You just don't redundantly annotate the operations
with the types

BE: I don't think frombits is a user concern

DH: This is a JavaScript DSL

RW: when you have uglifiers, like closure, it will alias builtins

PJ: that's OK, the declaration needs to be in the same context. if you look
at asm.js code, that's how it works currently

RW: my question was about the static knowability, WRT to JMC's point

DH: (explains how optimizer can determine that builtin is aliased)

BE: seems like the remaining complaint is too many methods

AWB: is there some fundamental API design that can reduce the number of

DH: I don't think counting the number of methods will lead to better design.

... The overall problem domain is affected by the combinatorics. It's a
large domain.

JMC: you're asking is there some alternate API design we could have? We
have as a group collectively tried to accomplish this, and we don't think
there is.

BE: signed vs. unsigned operators

JMC: feedback we got is that the API would be better with explicit types.
It goes against another constraint, lets have fewer functions.

AWB: my argument is have multiple types, but share functions between those

DE: Doesn't work in asm

AWB: short term trade off

BE: Explicit type instructions that map to hardware instructions
...SIMD is _only_ about hardware instructions

DE: equality semantics... should `-0 === 0` wanted to generalize to value
types, is this what we want? should it be SameValue?

AWB: if you have `Float32(0, 0, 0, 0) === Float32(-0, -0, -0, -0)`, how
should those be compared?

DE: we don't think this will be useful for devs at all, it just needs to be
defined. Simplest definition I could think of, and implementable

AWB: `===` gets applied to each of the elements?

DE: Correct.

AWB: Same issues that come up with scalar numbers in JS

positive and negative zero are equal, but NaNs aren't necessarily

DE: Could be that `===` is considered a "legacy"

AWB: I don't have the solution...

MM: Find deep equality with SameValue attractive

AWB: possibly, but I'm concerned about maps and sets. using a map for
memoization, key is a SIMD vector. you want to memoize float32x4
differently with +0 vs -0

let m = new Map();
m.set(Float32(0, 0, 0, 0), 1);
m.get(Float32(-0, -0, -0, -0)); // 1?

DE: Don't think anyone will do that.

MM: memoization is a strong argument

DE: I don't think memoization is useful for SIMD vectors

BE: used for constants.

MM: memoization is broken if you don't distinguish +0 and -0, e.g. dividing
by this produces positive or negative inf
... Any NaN contained, must be not equal.

DE: you already have to do that with floats.

MM: not if we say that === is non-reflixive with the values

DE: Impemented in some browsers, seem convenient to us.

MM: strong preference. when it is applied to anything other than direct
application to a scalar, mathematical equivalence class must be reflexive

Discussion of `===` and `==` semantics.

DE: I wouldn't want to make different behavior for ==

AK: This is more appropriate for Brian to deal with; DE said it's not
important to SIMD.

DH: Is problematic for me that `NaN !== NaN`, except for when it's in a
SIMD value, eg. `Float32(NaN, 0, 0, 0) === Float32(NaN, 0, 0, 0)`
... Only reasonable semantics: component-wise `===`, respect NaN

BE: it seems like we'll break with IEEE754

AWB: it seems logical that === should propagate out through the components
for value types

BE: Do SIMD programmers want all NaNs to not equal?

JMC: Yes

BE: Do SIMD programmers want -0 to equal 0?

JMC: Yes

MM: Understand -0/+0, by why NaN semantics?

AWB: my only concern with the present design is WRT maps and sets. we
decided to use SameValueZero

let m = new Map();
m.set(Float32(0, 0, 0, 0), 1);
m.get(Float32(-0, -0, -0, -0)); // 1?

AWB: we could define SameValueZero for vectors to not distinguish + and -

DH: we want SameValueZero and === to be recursively defined

DH: nobody expects 0 and -0 to be different in a set, nor do they expect
NaN to be different

RW: And has, get will behave accordingly:

let m = new Map();
m.set(NaN, 1);
m.has(NaN); // true
m.get(NaN); // 1
// even though NaNs are not `===` equal.

DE: we assume that SIMD users are more clever and will not be confused by

MM: we all agree that SameValue recursively does SameValue. My preference
is that all of them recur with SameValue. Next... (missed the specifics
here, sorry)

... in order to implement SameValue, if x != x && y != y then return true;
else ... it knows that NaN is a bizarre case, and it tests for it
explicitly. It knows that 0 and -0 are weird and test for it explicitly.
That coding pattern is copied a lot

BE: this won't get any better with this

MM: I'm not suggesting that SIMD.js diverge, just for value types

DE: Brian, do you have an opinion?

BT: I'm in Dave Camps

MM: I'm going to register an objection, but if no one else agrees, then
I'll let all these recur on themselves.

AWB: that's how value types should work, still concerned about maps. Maybe
we should revisit for maps an explicit comparison function.


BE: We have unfinished business with map

DE: We have an objection registered, but consensus on the current equality

Discussion of min/max vs minnum maxnum. Defined by IEEE754, related to NaN
behavior. minnum/maxnum will return the other value if one is a NaN

JMC: confirms that IEEE754 defines min num, max num


discussion about including length in SIMD operations

MS: Resolution on built-in module?

DH: Need module loading completed

AWB: Don't need this

YK: Signed up for this previously, can restart work on it.

DH: Browser vendors are blocked on loader api

AWB: we should as a matter of policy, call an end to adding new globals

DD: I don't agree, the global object is where you put these things

DH: aspirational, but not there yet

AWB: Stage 3 means API is frozen.

DE: There is an outstanding API question re: `{load|store}[123]`
(`load1(...)`, `load2(...)`), that needs to be investigated. Potential
performance cliff.

YK: TLDR here is if you still want to make this change, you need to signal
to the implementors that this is what stage 3 means

DE: Can decide now that we're not going to do this change.

PJ: problem is that we want people to use constants for accesing the lane,
but they don't have to, and that needs to work

JHD: how hard would it be to split the load/store methods into stage 2, and
the others move to stage 3. Does it work without those methods?

AWB: you could code the equivalent, not as efficiently

BE: will we learn more to help us decide?

JMC: this is a relatively new suggestion. I don't think we'll learn
anything new performance-wise. If compiler cannot be sure that it is a
constant, it can choose not to optimize. Let's just make a call

DG: difference from extract lane: there are indexes in bounds that we can't
be sure to make fast. Slow and tricky to implement

DE: behavior is strange to have operation throw if it would be slow

AWB: Still alot to work on in the spec. Is it at API freeze state or not?

BT: to the best of our knowledge, no changes.

AWB: enough thorough review of this large and complex addition to the

BE: SIMD seems stable. it's funky but its gone through the paces for stage
3. We wanted it for 262 because it blazes the trail for value types

AWB: more comfortable in another spec

#### Conclusion/Resolution

- Stage 3 Approval
- `{load|store}[123]`
- Consensus on existing
- Equality Semantics
- Consensus on existing
- An Objection from MM
- Work to do on Maps and Sets

## 10 Tooling Update

(Brian Terlson)

BT: All proposals are now using ecmarkup

- 402 Complete
- 262 In progress

CM: Need improved workflow documentation.

AWB: Concerns about general public review; diffs not ideal

YK/DD: will review visual, structural diffing tools to add to workflow

#### Conclusion/Resolution

- Write up workflow documentation.
- Review and recommend visual, structural diffing tools to add to workflow
- Move 262 to Ecmarkup

## 5.4 Updates on class-properties proposal

(Jeff Morrison)

JM: (updating)

YK: Decorator interop, with this proposal, needs reflection

JM: Don't decorators operate on the instance?

YK: Unrelated, decorators are described in terms of descriptors.

MM: How do class instance properties interop with decorators?

... Revisiting the proposal semantics.

MM: Expression itself is evaluated once per instantiation?

YK/JM: Yes

AWB: How does inheritance work?

JM: Each property and expression is evaluated in top down order as a result
of `super()` in `constructor() {}`

YK: Mark suggests that these go in the constructor

BE: Problematic:

class C {
  ha = eval(args)

var args = "arguments";
var huh = new C();
console.log(huh.ha); // ?

JM: as written, the `this` binding is the object that's been instantiated.

DD: This is an issue, the lexical scope is unclear

BE: But there is a "secret" thunk scope

JM: Users have been using this in Babel without any confusion about the
expression being delayed or defered.

Discussion about `arguments` and `this`

MM: How is this an improvement over ?

DH: (responding to alt proposal) the syntax isn't good.

- The class body is for declarative parts of the object template
- The constructor body is for imperative initialization parts

Easy to get caught up in semantics and lose sight of syntax.

MM: Disagree. Convention to follow: always begin a class by putting the
constructor first and in the constructor, properties declared, then blacnk
line (for organization).

RW/AWB: Where does super go?

MM: This is an open question. Depends on what you need to do with instance
properties and when

Discussion comparing:

class Point {
  constructor(x, y) {
    public this.x = x;
    public this.y = y;


class Point {
  public this.x = x;
  public this.y = y;

  constructor(x, y) {
    // ...

`x` and `y` not in scope.


class Stuff {
  autoBound = () => {

  id = getId();

DD: This SHOULD be written in the constructor.

RW: Completely agree, and also concerned with:

class Stuff {
  a = () => {
  b() {


AWB: And what is `arguments` in that arrow?
JM: Same as arguments immediately before the class declaration:

function foo() {
    arguments; // same
    class Bar {
        a = () => {
            arguments; // same


Discussion comparing the merits of Mark's proposal vs. Jeff's proposal.

MM: These declarations should result in non-configurable properties.

YK: Disagree.

#### Conclusion/Resolution
- Move to stage 1
- Jeff will follow up with Mark to further discuss his counter-proposal,
and Allen to further discuss his thoughts on private properties
- Jeff will update proposal to store property declarations in slots (rather
than container on prototype)
- Jeff will include reflection API for introspecting/reflecting declared

# Sept 23 2015 Meeting Notes

Allen Wirfs-Brock (AWB), Sebastian Markbage (SM), Jafar Husain (JH), Eric
Farriauolo (EF), Caridy Patino (CP), Mark Miller (MM), Adam Klein (AK),
Michael Ficarra (MF), Peter Jensen (PJ), Domenic Denicola (DD), Jordan
Harband (JHD), Chip Morningstar (CM), Brian Terlson (BT), John Neumann
 (JN), Dave Herman (DH), Brendan Eich (BE), Rick Waldron (RW), Yehuda Katz
(YK), Jeff Morrison (JM), Lee Byron (LB), Daniel Ehrenberg (DE), Ben Smith
(BS), Lars Hansen (LH), Nagy Hostafa (NH), Michael Saboff (MS), John
Buchanan (JB), Gorkem Yakin (GY), Stefan Penner (SP)

## 5.5 Decorators Update

(Yehuda Katz)

YK: Consider this an exploration in several cross cutting features that are
in development.

Starting at

class Person {
  @reader _first = "Andreas";
  @reader _last = "Rossberg";

let andreas = new Person();
andreas.first // "Andreas"
andreas.last // "Rossberg"

The `@reader` decorator has created the getters for `first` and `last`. ie.

class Person {
  @reader _first = "Andreas";
  @reader _last = "Rossberg";

// Actually produces...

class Person {
  _first = "Andreas";
  _last = "Rossberg";

  get first() { return this._first; }
  get last() { return this._last; }

Assume `@reader` is defined as:

function reader(target, descriptor) {
  let { enumerable, configurable, property: { name, get }, hint } =

  // extractPublicName('_first') === 'first'
  let publicName = extractPublicName(name() /* extract computed property

  // define a public accessor: get first() { return this._first; }
  Object.defineProperty(target, publicName, {
    // give the public reader the same enumerability and configurability
    // as the property it's decorating
    enumerable, configurable, get: function() { return get(this, name); }

function extractPublicName(name) {
  // Symbol(first) -> first
  if (typeof name === 'symbol') return String(name).slice(7, -1);

  // _first -> first
  return name.slice(1);

AWB: How is `super` treated, when encountered?

YK: Not yet considered, avoiding entanglement with yet to exist features,
trying to stay future proof to account for them.

Moving on to:

DH: Decorators vs. macros: staging. Decorators good next step

YK: Consider decorators a meta programming facilities.

Basic Rules of Decorators:

- Decorators always operate on a particular syntactic element, providing a
hook into the runtime semantics for that syntax.
- If the runtime semantics for the syntax include `let x be the result of
evaluating SomeExpression`, that expression is passed into the decorator as
a function that, when called, evaluates the expression (a "thunk").
- Decorators are not macros: they cannot introduce new bindings into the
scope and cannot see any downstream syntax. They are restricted to
operating on a local declaration using reflection tools.

Looking at:

AWB: Why not capture the property key, could be computed property

YK: Don't want to make that policy decision, but can revisit.


YK: general open question about whether a decorator function has to return
a descriptor or not. alternatives like "false => cancel property creation"
or "undefined" to keep going untouched, etc
...explanation of "decorate" implementation in the appendix, which is
semantics, but not API.

DH: question about if decorators have to be identifiers, or LHS

YK: (explaining how computed and uninitialized property decorators would
work the same)

YK: static properties would be treated the same as object literal
properties, as type "property" instead of type "field"

Discussion re: `static @reader` vs. `@reader static`

YK: you have to decide where to put the decorator, I've always put it to
the right. Usually modifying the builtin thing

AWB: I've always thought of it as modifying the declaration

_question about shadowing symbol bindings in Methods example, update

YK: easy to create shadowing hazards with symbols and function args

(explanation of decoration on properties in object literals using shorthand

DH: basically the hint is a tag to explain to the decorator function the
context being used

YK: yes, this is a motivating example

AWB: ambiguity here? can't tell whether the user wants to initialize to
null vs. normal shorthand syntax

YK: it's up to the decorator to decide the semantics

YK: simplest solution is to say that you have to type @reader _first:
undefined directly

YK: but my suggestion is to allow decorator to decide

(describing how the motivating example would look in MM's syntax)
public @reader this._first = first;

YK: feel less strongly about how in-constructor declaration is bad. Moving
@reader to the right of public

DH: I don't think that's the issue. more important that properties are at
the toplevel of class

YK: not arguing one way or the other for "initialization in constructors or
not" but trying to demonstrate that that question is orthogonal to this

MM: accept that this is orthogonal

YK: _showing syntax alternatives for privates, not trying to bikeshed_

YK: in this hypothetical privates scenario, subclasses would not have
access to superclasses' "private" fields, ie, lexical scope

YK: no reflection API to get at privates outside of lexical class body, and
Proxies do not allow access to it

DH: if you want to think of it like weak map...

YK: that's not the programming model or representation. Reflect.construct
is a difference

DH: doesn't affact intercession

YK: from semantics perspective, very similar

Discussion of observable differences between weakmap and this

MM: only becomes observably different in the future were it could be reified

YK: I agree. My proposal doesn't make it a weakmap, but from a programmer
perspective, you could see it that way

AWB: difference: a mirror of private state needs to be presented to
decorator, mirror is presented at class definition time not instantiation

YK: there's one difference, it's a *read only* WeakMap - you aren't allowed
to set the fields

MM: about mirror: mirror is reflecting on the class...

AWB: no instance-level reflection

MM: why does the reification of the field name as part of the reification
of the class need to be able to give read access to the instance value

AWB: it doesn't

YK: TL;DR new metaproperty called class.slots, effectively a limited subset
of the weakmap API. only operation I care about is class.slots.for, gives
dictionary with private fields

MM: some reification of the name of the private fields?

YK: just the ones that are lexically available to the class definition.
Gives keys and values of properties declared

MM: why give the ability to read the instance value, but not to set the
intsance value

YK: sorry, imprecise. You can set private slots, cannot replace dictionary.
Think of it as non-configurable

MM: ok, good. reification is not quite a weak map, doesn't have ability to
delete. Violates the fixed shape constraint

AWB: agree details need to be figured out, but big picture sounds good

YK: (describing syntax class.slotsof)

MM: class.slotsof is a special form

YK: refers to a lexical binding, not value. wanted for ergonomic reasons,
if you need to do things on the class outside of the class definition
lexical scope

AWB/YK: better to try to move this inside the class definition, perhaps
with a static { ... } block inside the class definition

(discussion of accessing parent's slots from nested inner class)

DH: for this case, just use a local variable in parent scope, can be
accessed by inner class. maybe let bindings in class definition?

YK: class.slots reification mechanism is 90% sugar

DH: (example of let binding of class.slots in class toplevel so binding can
be accessed by inner class)

AWB: if you have this you have less need for static private slots

YK: static method that you invoke and delete immediately has same behavior

(discussion of private statics)

MM: thing that makes private statics different, for an instance, all
contributions are collected into one instance, in static it is spread out
over the prototype chain... should be able to let the prototype chain do
it's work

AWB: don't think so, what if you make an instance count static. now define
subclasses, don't they get their own instance count?

MM: but they can't access it

YK: (getting back to presentation)

YK: (explaining how slots.for is abstraction for get/set in decorator for
public vs. private properties)

(come back to field, slot, property distinction)

BE notes:
- class elements define properties of the class prototype, class statics of
the constructor
- JM's property declarations specify something else: instructions to run
from `[[Construct]]` before the constructor call
- this suggests using "field" as jargon for JM's public property
declarations and YK's private slot declarations
- field: instance property instruction specified by declarative new kind of
class element, public or private
- slot private field
AWB recalls ARB's V8 self-hosted JS has private slots, want them to pack in
instance storage

DD: cannot be allowed to run synchronous operations arbitrarily in all
constructor (HTML Elements, etc.)

YK: Agree, lock down reflection APIs

AWB: Any new reflection APIs should be reviewed by Mark for security


YK: Summary...

- Decorators on methods
- Decorators on object literal properties

Neither rely on some other proposal

DE: previous proposal mentioned function decorators

YK: Issues

- Staging
- Where does decorator go? It's clear with class and object literal, not
with function decl.


// TDZ on access vs invocation

addEventListener("error", onerror);

function onerror(...args) {


Unclear what this does.

DH: The decorator is not wrapping, is mutating existing object.

- not calling the decorator later.
- An identity decorator should be equivalent to not having a decorator at
- Becomes the one place a decorator is not wrapping.

Angular use case: want to decorate function declarations for unit testing.

DH: factor out function declaration decorators. Rather have an imperfect
decorator than none at all.

YK: Not actually proposing this.

MM: Happy with this at stage 1, no controversy.

YK: Important change: If expression, thunk on it.  (thunking in lieu of

AWB: is there specifically a name parameter that is that thunk?

YK: yes.

AWB: trying to understand various binding contexts where wouldnt want to
evaluate ...

YK: not confident that there is no case to defer evaluation

AWB: concerned about expressions _not_ being evaluated

Discussion, re: effect on computed and non-computed properties

JM: VM authors lose the ability to understand the shape?

YK: No

AWB: requires analysis at runtime, rather than compilation.

AK: might lose runtime fast path

DH: can't be any worse than existing policy of looking at the shape after
the constructor is done.

AK: Once you see decorator in literal, the VM gives up until sometime

YK: Doesn't mean it's slow

AK: In the short term, maybe.

DH: need to udnerstand challenges:

- already ahave machinery to analyze and find optimizations
- accept that decorators may have a slow first implementation
- why can't you then immediately optimize with existing machinery?

YK: Request moving presented today and "privates" (abstractly) to stage 1.
Want to think about future additions in terms of being decoratable.

DD: Not enough discussion re: decorating shorthand properties.

AWB: This is just part of feature design details.

AK: Don't understand the "bundle".

YK: Form a champion group to work forward these features as a group.

JM: Do something outside of committee.

- Private state
- Decorators
- Decoratable object literal properties

#### Conclusion/Resolution

- Remains at Stage 1 with all changes presented

## 5.3 Async Functions

(Brian Terlson)

BT: Stage 3 proposal?

- Waldemar has reviewed, changes in place.
- Yehuda and I agree on cancelation
- Believe that cancelation can be done later

YK: If you don't type `return` in your async function, no way to the return
path. May have written some finalization, but no way to guarantee

BT: Can write async that assumes some finalization, that might not happen.

YK: In the absence of cancelation, if there are no upstream promises to


async function foo() {
await delay(5000);

const p = foo();


// Would need to be...
async function foo() {

try {
await delay(5000);
} finally {

const p = foo();


If async functions forever stay non-cancelable, no issue. If all async
functions become cancelable, the hazard is introduced.

BT: async functions _must_ be cancelable. We won't add them unless they

- fulfilled: normal completion
- rejected: throw abrupt completion
- canceled: return abrupt completion
- ???: continue/break abrupt completion

JHD: q. about synchronous "return abrupt completion"

YK: Generator, call `return()`

"Return Abrupt Completion" is for any kind of return from current execution

BT: case where promise returned by async function, awaiting 5 promises? A
promise is canceled, reasonable to handle that promuse and move onto the
next thing—otherwise have to nest 5 try/finally deep.

Discussion of return, cancelation and recovery.

AWB: A new type of completion?

YK/BT: Yes

JHD: Clarify need for cancelation?

BT: Cancelation important, widely wanted, they will come to Promises, and
will not be able to use async functions for that. So needed for async.

Discussion re: promise cancelation, how to introduce it.

CM: clarification between the two main uses of a cancelation.

YK: Promises should be allowed to represent themselves as cancelable

CM: No disagreement.

JHD: maybe cancel is just the wrong name?

YK: cancel impacted design, want to make sure that adding cancel to async
function in the future wont pown them.

BT: haven't found significant issues with cancelation for async functions

- Subtle to add to Promises, but work needed
- No obvious issue to add to async function


async function foo() {
await delay(5000);
cleanup(); // <-- not called if canceled.


DE: Changes since last update?

BT: No relevant.

AK: Async arrows?

BT: Waldemar reported no issues.

DD: Should use try/finally to guarantee cleanup. Strictly a hazard if
someone starts calling `cancel()` on your promises.

BE: Does this push up need for finally method?

BT: Need more work there.

YK: `finally` is a handler, doesn't correspond to a completion record
change, but a cluster of completion records


async function foo() {

try {
await promise;
} catch cancel {
// recover and continue?
} finally {


BE: Add cancel to Promises, then ok for async/await

BT: finally is being conflated with cancelation

This is stage 0.

SP: A future where finally is important, if code written to expect, then

BE: Should use try/finally, regardless of await


BT: Chakra has implemented async/await on Edge. SpiderMonkey may have
implementation? In Babel, TypeScript, Flow.

DH: Confirmed active development in SpiderMonkey

JHD: (some q about try/finally)

SP: assume code written indefensively might fail.

More totally useful, important, completely clear and not repetitive
discussion about how bad code might fuck up if promises are canceled.

#### Conclusion/Resolution

- Stage 3 Approval

## ECMA 402 Update

RW: blah blah blah

AWB: A lot of proposals, what is the criteria for new additions

EF: Paving cow paths, otherwise remain in library code. Working on
proposals for plural and relative-time formatting.

CP: For ES2016, we will focus on exposing low level apis for existing
abstract methods. New features will probably arrive in ES2017.

DD: FirefoxOS devs discovered real needs that are being reported.

EF: Getting the locale data (e.g. CLDR data) into/accessible-by the
runtimes is a focus because it avoids haivng to transfer larges amounts of
data over the network. NumberFormat and DateTimeFormat have large amounts
of locale data to back their APIs; looking to do something similar for
plural and relative-time formatting proposals.

#### Conclusion/Resolution

- Send new HTML to Ecma

## 5.10 Proposal: String#padLeft / String#padRight

(Jordan Harband, Rick Waldron)

JHD: (run through history of proposal)

- min length vs. max length semantics? min length semantics with repeat.
max length is the desired functionality.

AWB: re: min length and max length, concerning unicode characters, code

JHD: Issues will exist in _any_ string apis. This API doesn't use code
points, can be changed to do so. Length property wouldn't be useful. If
filler is a surrogate pair, I can use a multiple of it's length...

- Max length is in code points?

DH: re: terminal output, do control characters count against length?

JHD: Yes, always.

Discussion, re: code points vs. latin centric characters

BT: This API is no different than existing APIs

JHD: really want to solve this? Change everything to use graphemes

AWB: interpret "length" as simply: "number of occurrences of your fill

DD: assumes the rest of your string is Emoji. Never going to get the width

AWB: if it doesn't do the right thing in the real world, why?

BT: Trying to do things beyond the simplest use case is just untenable.

RW: Intl could adopt responsibility for a non-latin character set handling?

BT: Agree.

Derailed into discussion about what gets to go in the standard library and
what gets defined in a standard module.

DH: (To Rick) Not cool to attack other specs when inclusion of proposal is

Note: I made a comment that if two string methods are "too much", then we
should revisit SIMD for the same concerns.

Back to padLeft, padRight...

DH: Clearly important if implementers are agreeing to implement before
other features.

Discussion re: stage 1 or 2?

AWB: For stage 2, controversy resolved.

JHD: Then stage 1.

#### Conclusion/Resolution

- Stage 1
- Reviewers to be assigned.

## 5.11 Proposal: Object.values / Object.entries

(Jordan Harband)

JHD: Need is obvious.

Question about return: iterable or array? Spec wants to be an array.

DH: Confirm, when array you get a snapshot. If an iterator, then updates
would be shown, which breaks from `keys`

#### Conclusion/Resolution

- Stage 2 Approval

## 5.12 Proposal: String#matchAll

(Jordan Harband)

JHD: pass a regex, returns an iterator, each yield returns what exec would.


- doesn't accept a string, not coercion
- always adds the "g" flag
- makes a "copy" of regexp to avoid mutating

BE: reason for not including string?

JHD: Enforces a better practice

AWB/BE: valid, but creates an inconsistency, should be updated to include

JHD: Will update then.

AWB: Needs to work with RegExp subclass as well.

DE: Will call RegExp.prototype.exec, can leak the RegExp.


Specify as `@@matchAll`

AWB: Default impl of `@@matchAll`, see default `@@match`

DD: Not a lot of "library" code

BE: Won't find it there, it's generally in "open code". Steve Levithan
wrote about this.

YK: Ruby has a scan method, which I use frequently.

DD: an alternate: add another flag that avoid global state


DE: Still leaks.

Can we avoid the observable "cloning"?

BE: Take back to work through this

Discussion of algorithm approaches.

YK: Missing? A thing that's like exec, but gives you back the lastIndex?

AWB: `exec()` could grow an additional argument for start position.

The name stinks, but nothing really better.

- `matchEach`? It produces an iterator... (some agreement)


#### Conclusion/Resolution

- Stage 1 approval
- Accept strings
- Allow RegExp subclass
- Default impl of `@@matchAll`, see default `@@match`

## 5.9 Trailing commas in function parameter lists

(Jeff Morrison)

JM: Updates since previous...

MF: Change arity? Object, array...

RW: No, ignored.

YK: Symmetry with arrays? Holes on the call side?


BE: (revisit C issues with trailing commas)



- evaluation rules
- static semantics rules

BT: Don't need to block on this, can be delivered later.

Quick run through trailing comma in parenthetical expressions


#### Conclusion/Resolution

- Stage 2
- Reviewers?
- Michael Ficarra
- Brian Terlson

## Process Discussion

- A plenary day
- Two presentation and discussion days

### Exponentiation Operator

RW: Precedence issues:

BE (On whiteboard): -x^y in math and every other language means -(x^y)

Old spec is (-x)^y

AWB: Does the potential confusion of this (whichever way it happens to be
decided) suggest we should pull it out?

BE: No, math and every other programming language do it this way...

AWB: I agree if there is an exponentiation operator the precedence should
be followed going back to math. Since this potential confusion has been
identified, we have a perfectly good way to do this...

RW: This is a case of the new process working as it should - implementers
gave feedback, proposal is now better.

YK: Arguing for -5 ** 2 being (-5) ** 2 because people will think that's
how it works.

YK: I think minus is kind of an edge case and I'm happy with this either
way. Is my intuition wrong? If everyone else thinks the answer of what the
proposal is now, then fine.

BE: Problem is people thinking minus is part of the literal.

DH: For math it seems obvious that -5^2. But for -5 ** 2, because of the
whitespace around the infix operator. Even without space, - seems to be
part of the literal.

BT: Python docs says don't use space.

YK: Doesn't JS precedence win over all other precedence?

RW: Jason's intution matches that of all other programming languages that
has intuition operator.

YK: This is cargo culting.

BE: Let's say that fortran did it to be mathy and everyone copied it.
There's still a precedence argument.

YK: I'm a rubyist. I had to look up what is in ruby. People don't know ow
it works.

DH: We are operating in the context of an industry that gets expectation
from historical context or JavaScript operators?

BE: You should be parenthesizing.

RW: Coffee's ** operator matches Python and Math and Ruby.

JH: Will value types complicate this? Will people copy/paste from C
programs or other things?
JS is eating the world. This will cause friction if we break historical

YK: I don't copy/paste code from other languages.

BE: Options: 1) wall of confusion, do nothing. 2) math/programming language
precedence. 3) Javascript/dave/unary minus binds tighter people.

RW: Mark advocates for abandon/withdraw (1)

BE: Let's vote...

1: 4, 2: 15, 3: 2 (including MM virtual vote)

DH: Let's be clear - people might copy code I guess, but effectively zero
people have an intutition about this from other languages. Agree people
have an itutition that ** is the exponentiation operator. But people
usually try to avoid dark corners so they never develop an intuition for
negative bases.

I also reject that we must do what math does.

DD: I disagree.

BE: New option: 4 - it is an error to combine ** with unary minus. Code you
port doesn't have this almost for sure.

No consensus... people are leaving.

# Sept 24 2015 Meeting Notes

Allen Wirfs-Brock (AWB), Sebastian Markbage (SM), Jafar Husain (JH), Eric
Farriauolo (EF), Caridy Patino (CP), Mark Miller (MM), Adam Klein (AK),
Michael Ficarra (MF), Peter Jensen (PJ), Jordan Harband (JHD), Chip
Morningstar (CM), Brian Terlson (BT), John Neumann  (JN), Dave Herman (DH),
Rick Waldron (RW), Yehuda Katz (YK), Jeff Morrison (JM), Lee Byron (LB),
Daniel Ehrenberg (DE), Ben Smith (BS), Lars Hansen (LH), Nagy Hostafa (NH),
Michael Saboff (MS), John Buchanan (JB), Gorkem Yakin (GY), Stefan Penner

On the phone: Mark Miller (MM), Istvan Sebastian (IS)

## Exponentiation Operator

RW: BE suggested option 4 yesterday (throw when unary negative is used
without parens)

// Ok
let z = K - x ** y;

// No Ok
let z = -x ** y; // Syntax Error

// Must be:
-(x ** y)

// Enforced by grammar change, just a SyntaxError

RW: BE wrote up option 4 and a summary and emailed to esdiscuss

RW: _similar to TDZ: an error when something ambiguous happens_

RW: AWB + MM switches 1 vote to 4, RW switches 2 vote to 4.

RW: question to group: do we have consensus on stage 3 with option 4?

AK: i think this sucks for users

RW: only when the user does something ambiguous

AK: we already have Math.pow which is unambiguous. why add another way that
has ambiguity concerns? it looks confusing to me as a user.

AWB: it requires that you put in parens, what a careful developer would
already put in parens

RW: considering your feedback (a syntax error would be a bummer) are you
willing to block consensus?

DH: I will push spidermonkey team to display a better error in this case

AK: i think it's just fine to choose one (ie option 2 or 3) and i chose
option 2

DH: that's just going to be a bug farm

BT: like it is in every other language?

DH: yes.

YK: there's bugs in every other language, but we don't have to copy those
bugs into JS

RW: this is sufficiently useful to the end-developer

DH: Here's another way of looking at it: there is a natural ambiguity
between two historical precedents, reasonable to expect it to go one way or
the other. Don't just pick one because it will confuse people who expect
the other. Making it an early error to avoid the ambiguity is good software
engineering practice

AK: why do you think other langs (with exp operator) don't make this an

YK: they cargo-culted it.

AWB: some of them actually have negative numeric literals (option 3) baked
in to the language.

DH: so -1 actually ends up doing the right thing...

AK: I'm not the only one who thinks this, Waldemar might think this too

RW: I don't think so; Waldemar supported requiring parens early on

DH: very recent precedent for exactly this kind of decision when andreas
proposed that "use strict" implications for parameter lists were ambiguous;
we decided to make all of the ambiguous cases SyntaxErrors to avoid
confusing people one way or another. That was a good decision, this is
similar. Let's not knowingly create an ambiguity where both are reasonable

MM: in agreement with Dave, avoid misinterpration where the consequence is
the program proceeding without diagnostic that defies user expectation

MM: ... proceeds without a diagnostic that violates user expectations.

AWB: if we're wrong about this and get tons of complaints, we can always
remove the SyntaxError and select options 2 or 3 later.

DH: Oh, python has the same error... -1**2 == -1

AWB: maybe Matlab...

RW: concerns enough to block consensus?

MS: i agree with AK; i don't like option 4. we'll implement the spec but I
think it's unnecessary complications given other languages.

BT: I think it is unnecessary, but I don't care

YK: Do you agree, if we pick 2 or 3 there are some users who will pick the
wrong one

BT: yes, but that's true for everything that includes precedence. We don't
make all things an error where precedence is ambiguous.

YK: there are different kinds of confusion, mixing operator classes is an
especially bad kind of confusion

AK: use strict in parameter list is different -- had implementor concern as
(discussion of "use strict" w/ parameter list, comparison with this case)

YK: BT, your point about general operator precedence is valid. I wondre why
the difference from the normal precedence... why is changing the precedence
in a precedence class not a red flag?

BT: I'm not sure people talk about operators in terms of precedence classes

DH: I think people do -- I do. I don't remember factoring rules for BNF, I
think of it terms of whitespace and "tightness" or "looseness"

AK: it was useful to see the thoughts yesterday. another straw poll would
help me see if i'm an outlier or not.

YK: option 5 of "i don't care" please

RW/YK: let's say: 1 is "do nothing". inaction.

BT: I violently don't care

MF: let me remind the room; option 4 doesn't prevent options 2 or 3 later.

1. Dropped                                                    0
2. Hold @ current proposal  (-5 ** 2 => 25)  3
3. Orig Proposal (-5 ** 2 => -25)                   0
4. BE syntax                                                11
5. IDGAF                                                       3

RW: we can still relax the syntax error

AK: rare enough case that it likely won't happen

DH: I'll prototype a good error in my own parser

#### Conclusion/Resolution

- Stage 3, with the provision that option 4 goes in

## 8. Test262 Update

(Gorkem Yakin)

GY: (General update on status of ES6/ES2015 support in test262)

BT: previously we decided it was important to have clear delineation
between test artifacts at specific spec versions, but that's hard.

YK: It stops making so much sense now. Can I suggest a feature flag thing?
(discussion about how to handle old tests that break with a new version)

YK: at any point in time, take a snapshot of all stage 4 features and
that's what we give to ECMA

AWB: strictly speaking, only yearly releases approved by GA that are final

AWB: nothing becomes stage 4 until version of the spec they're in is
(more discussion about stage 4 vs. stage 5)

BT: I see it this way. for implementors, there is value in having tests
checked in to test262 when they're working on the features, ~ stage 2/3.
Only consideration here is what implemetors find useful

YK: ok stage 3 seems fine

BT: if things break, git has tools for this. going forward let's not have
branches, just say test262 is living

AK: I say stage 3

(RW agree, this aligns with implementation step)

YK: I think stage 2 criteria is test262 tests. For me, as spec author this
is valuable

AWB: during stage 2, I expect these to change a lot. These are part of the

DE: for the SIMD tests, we went through a lot of churn. it makes sense to
have them outside of test262, now we're stage 3, we're ok with test262

YK: I think that implementors should have commit access to test262 while
they're working on it

BT: difficulty mentioned by DE is real

YK: not intractable to make this frictionless

BT: I don't think this is too bad, having written thousands myself. Not
frictionless, but surmountable

YK: this sounds like a real blocker. proposal: I think you should be able
to put all tests for a feature in a file, people who are working on stage2
and up features should have commit access

BT/DE: we should use pull request model

AK: nice for implementor to know these are stable, stage 3 is nice

(discussing whether we need to use pull requests vs. direct commit access)

DE: problem with stage 2 is that the API is not stable, so it doesn't
provide value

DH: having tests are similar to having spec, helpful to make it clear to
people how the feature works

AK: we have automated process pulling test262, we don't want to have to
triage unstable changes

YK: feature flags should solve this problem

BT: difficulty is that numerous different test262 harnesses, I understand
Google has their own

_ general agreement that test262 tests should be stage 3 _

DE: YK and others are going to look into adding feature flags to
implementors test262 harnesses

BT: difficult to test features in isolation, they are often cross-cutting

_ discussion about difficulty of implementing feature flags _

AWB: what is the plan of record for user-facing test page?

BT: someone has to fund this work. Someone in Microsoft working part-time
on this, build scripts to package the tests into a site. Maybe get UI guy
to spend some time on it

MF: why do we want this?

BT: useful as a marketing feature, show how accurate your browser is

AWB: original motivation: valuable to have vendor-independent neutral test,
not subject to gaming

JHD: easy to test in browser with a web link, harder with a harness

AWB: if we think it's valuable to have a website where users can run tests
against multiple browsers, then some members have to step up and do the
work or foot the bill. Otherwise take away the website

BT: money problem right now. accomplished webdev, about a month of effort

#### Conclusion/Resolution

- Test262 is "living"

## 5.6 Proposal: call constructor

(Yehuda Katz)

YK: (from proposal)

- ES5 constructors had a dual-purpose: they got invoked both when the
constructor was newed (`[[Construct]]`) and when it was called (`[[Call]]`).
This made it possible to use a single constructor for both purposes, but
required constructor writers to defend against consumers accidentally
`[[Call]]`ing the constructor.
- ES6 classes do not support `[[Call]]`ing the constructor at all, which
means that classes do not need to defend themselves against being
inadvertantly `[[Call]]`ed.
- In ES6, if you want to implement a constructor that can be both
`[[Call]]`ed and `[[Construct]]`ed, you can write the constructor as an ES5
function, and use `` to differentiate between the two cases.

Motivating Example

The "callable constructor" pattern is very common in JavaScript itself, so
I will use `Date` to illustrate how you can use an ES5 function to
implement a reliable callable constructor in ES6.

// these functions are defined in the appendix
import { initializeDate, ToDateString } from './date-implementation';

export function Date(...args) {
  if ( {
    // [[Construct]] branch
    initializeDate(this, ...args);
  } else {
    // [[Call]] branch
    return ToDateString(clockGetTime());

This works fine, but it has two problems:

1. It requires the use of ES5 function as constructors. In an ideal world,
new classes would be written using class syntax.
2. It uses a meta-property, `` to disambiguate the two paths, but
its meaning is not apparent to those not familiar with the meta-property.

This proposal proposes new syntax that allows you to express "callable
constructor" in class syntax.


- The presence of a `call constructor` in a class body installs the call
constructor function in the `[[Call]]` slot of the constructed class.
- It does not affect subclasses, which means that subclasses still have a
throwing `[[Call]]`, unless they explicitly define their own call
constructor (subclasses do not inherit calling behavior by default).
- As in methods, `super()` in a call constructor is a static error,
future-proofing us for a potential context-sensitive `super()` proposal.

import { initializeDate, ToDateString } from './date-implementation';
class Date {
  constructor(...args) {
    initializeDate(super(), ...args);

  call constructor() {
    return ToDateString(clockGetTime());

AWB: This is an exceptional example, most cases just defer to `new`, where
this goes off on some other operation.


class A {
  constructor() {
    this.aProp = 1;
class B extends A {
  constructor() {
    this.bProp = 1;
  call constructor() {
    return new B();

class C extends B {
  constructor() {
    this.cProp = 1;

let b = B();

b.aProp === 1; // true
b.bProp === 1; // true

let c = C(); // throws! there is no call constructor here

AWB: Think about it, not as a property added to the prototype, but as an
alternative to the `constructor`

MM: interaction with Proxy call trap?

AWB: class with a call constructor get a distinct `[[Call]]` that knows how
to dispatch to the user defined behavior. proposal yet for reflection toString yet.

MM: toString the constructor, you get the entire class

JHD: currently unspecified in ES6; some engines give the "class", some give
the constructor, some give a function that has no indication it was a

YK: Then it would be included.

YK: _shows `call constructor() {}` vs `() {}` inside a "class"_

Mark's Alternative:

import { initializeDate, ToDateString } from './date-implementation';
class Date {
  constructor(...args) {
    initializeDate(super(), ...args);
  () {
    return ToDateString(clockGetTime());

AWB: i don't like it because you could forget the method name

YK: also conflicting with square bracket syntax and arrow functions
_lots of agreement that this is confusing_

MM: happy to drop it; glad to have a reaction.

DH: only thing that gives me pause is Stroustrup's principle: new stuff,
people want long syntax; later, people want short syntax.

MF: May want a decorator augmenting a call constructor (Michael, I missed
the tail end of this, can you fill in?)


MS: would this allow you to omit the `constructor`?

YK: class would create a default `constructor`, but otherwise behave like a

_discussion about callable non-constructable classes; general consensus is
that you should use a function for this_

DH: Like this b/c it matches built-ins and defines a clear separation of

AWB: _discussing built-ins that create wrappers_
... Don't need to add sloppy mode semantics for built-ins, eg. SIMD

JHD: it's an axiom that `Object(x) === x` if it's an object, and not if
it's a primitive. This must be preserved.

MM: Object.prototype.toValue, auto-wraps `this`.

AWB: Then unwraps

JHD: Every JS value must be wrapped when pass through `Object`.

AWB: Not saying "no wrapper", needs wrapper to do method lookup

DE: Sounds like two versions of ToObject?

JHD: in a sloppy mode function, if i do ` = "bar";`, and `this`
isn't `undefined`, it *always* sets the property such that `` can
be retrieved immediately after. If `this` is a primitive, this isn't the
case. If we change the auto-wrapping behavior of "this" in sloppy mode, for
**any value**, then this will break existing code.

AK: Not going to add reflection here?

YK: No, but reflection is needed.

AK: Will it "grow" reflection?

AWB: We hope to advance this to ES2016

YK: Reflection is needed along side decorators and this proposal, but don't
want to block this on decorators.

AWB: No reflective way to change a function with toString, but can see it's
whole body.
...tweak toString, for class with a call constructor, include it in the
toString representation

MM: Should be the entire class definition

DH: ??

AWB: That position is contraversial

MM: Thought we agreed?

YK: Bigger toString issue.

AWB: For 2016, toString should at least include call constructor body

MF: Want added restrictions before 2016, we can limit the reform proposal
to buy time.

_This can be implemented in terms of ``._

AWB: Nec. in support of decorators:

- If you want decorators to be able to create call constructors, there
needs to be some reflective way to install them.

AK/BT: _discussion potential implementation details_

#### Conclusion/Resolution

- Stage 1 Approval
- toString includes call constructor body in output
- Goal for Stage 3 next meeting.

## Secretariat


- Only Ecma-404 will be fast tracked.
- Bugs in Ecma-402 need to be addressed.
- ES2016, 17, 18, etc. might cause issues?

I can't really understand most of what's being said over the polycom.

Sounds like ES6 has a lot of downloads

## Meeting Schedule


- November 17 - 19, 2015 (San Jose - Paypal)
- January 26 - 28, 2016 (San Francisco - Salesforce)
- March 29-31, 2016 (San Francisco - Google)
- May 24 - 26, 2016 (Europe)
- July 26 - 28, 2016 (Redmond - Microsoft)
- September 27 - 29, 2016 (Los Gatos - Netflix)
- November 29 - 30 - December 1, 2016 (Menlo Park - Facebook)

#### Conclusion/Resolution

- Need to confirm Munich in May
- Rick, Dave will figure out March

## 5.13 Updates on rest properties proposal

(Sebastian Markbage)


var o = Object.create({ x: 1, y: 2 });
o.z = 3;

var x, y, z;

// Destructuring assignment allows nested object
({ x, ...{ y, z } } = o);

x; // 1
y; // undefined
z; // 3

AWB: Object pattern destructuring doesn't check enumerability, just goes by
property name

DH: The `...` means "I'm enumerating the names"

SM: ie. getting the keys

AK: What about in the binding case?

SM: Consistency. The BindingRestElement only allows an identifier.

SM: I will write a proposal to fix BindingRestElement to allow nested

#### Conclusion/Resolution

- No stage change

## 6. Updates on Loader

(Dave Herman)

DH: _introduction_

BT: crass question: will we have something to implement soon?

DH: all you need to get started implementing is a basic understanding of
what the really core name resolution is going to look like.

BT: and that's done?

DH: it's done *enough* that you could be hacking on this now. not written
in the spec yet.

BT: Concerns that if spec is not written and we implement, it might be
useless. Stuck in holding pattern.

DH: Should start hacking on this.

DH: we will get you stage 0 stuff written as soon as we can.

BT: (wants estimate to communicate to Edge team)

DH: We can promise name resolution drafted in the spec by the next TC39

JM: How are relative urls resolved? Relative to what? (toplevel document?
importing module url?)

DH: "referrer" used for relative, "/"?

DH: _explains how "module src" will respect base url, but imports inside
the module will not_

MM: Loader constructor has no concept of URLs, just name resolution.

DH: Loader class is generic. Specific default Loader has to be host
specific, there is a spec.

AK: Who are the experts working on the Loader spec? Anne? Dimitri (Glazkov)?

DH: Both have reached out. Let's have a meeting with those people.

AK: Dimitri is quite busy, so...

YK: I think it's important for Anne to be involved here.

DH: script type = module should have roughly defer semantics, asynchronous
but ordered.

YK: before doc ready, content loaded

DH: We have to asynchronously load the deps, do we have to complete the
compile phase of first script type = module, or ... execution phase as well

YK: argument for deferring evaluation at all, first is ... if you move on
to second, your script didn't get a chance to configure...

... you cannot start download script type = module imports before ...

AK: this is all about what script tags do right now

YK: you need to have one block. this block is for configuring my loader, I
don't want any scripts to load before this is done. Not good to block
loading modules before all scripts are loaded

DH: if semantics of type=module is only that one has to precede the
compilation of the other, forces you to use legacy script.

YK: there's a worse problem, path for legacy script => legacy blocking
script, or use legacy defer script, and now you have to decide order
between them. Another option is loader config, that has to run before, but
not other scripts

DH: a narrow case? Could have a syntax instead of reusing form?

YK: if you try to make other scripts ordered, you have to speculate whether
one is a loader

DH: Another Q: Allow completed subgraphs to execute early? Hold the line on
deterministic top level execution.

Issue: module system forces sequentiality

- download
- get deps
- download
- then start compiling


- May create latency
- Could a subgraph that was completed start executing?

MM: what would be the definition of a completed subgraph that distinguishes

DH: for example, toplevel module main, requires foo and bar, foo requires
jquery, bar requires 100 modules. While bar is downloading dependencies,
foo is downloaded jquery, waiting to compile and run. In that case,
schedule foo and jquery's top levels to run, more concurrent semantics,
less deterministic

MM: makes sense, introduces new element. optionally breaking toplevel
module execution into separate turns. multiple modules part of 1 dependency
graph may be executed in separate turns

YK: middle ground: start executing subgraphs in the order they've been
specified. gives you determinstic ordering

AWB: in terms of modules, there is only one syntactially type of module.
two types written: script type modules, root of execution, import other
things. OTOH, module-like modules have exports and imports and logically
are doing useful work if people import them. I thought that module-like
module would never be initialized if someone didn't import it. In theory, a
script tag that names a module-like module, doesn't have to be executed
unless a script-like module imports a module-like module.

DH: no interest in inline-named modules

AWB: not relevant to this discussion.

AWB: script-like module: used like a script, doesn't have exports, does
have imports, written for effect

DH: either are there, b/c in a script tag, or not.

AWB: so you write a script tag, name a script-like module, that needs to
execute as soon as the deps are available.

JM: has to wait for deps?

AWB: it can't run until it's script is available. Here is code I want to
execute. If you name the script whose exist to export it, but nobody uses
it. What does a module script tag mean, this gets to the deferred
semantics. Here is the script, I want to evaluate this, even if nobody
depends on it.

DH: No. Cannnot express the former in HTML. The module doesn't have name,
cannot be depended on.

DH/YK: they have source but they don't have name.

AWB: Anything in a script tag is the root, execute directly. Assume ordered?

DH: _confirms_. Intentional order of execution. Code directly or indirectly
depended on has to execute immediately. Does all that have to happen in a
single event turn? Or across several? If the subgraph has completed, can

MM: bottom-up execution constraint. clearly doesn't imply any type of
suspended caller. If all module execution is executed in single turn, then
starts and ends with empty stack.
 implementations can do whatever they feel like to do other jobs

DH: (explaining options between single job vs. multi-job loading. if
multi-job, then decision between total ordering and partial ordering)
1. single job
2.a. total ordering of modules N jobs
2.b. partial ordering of modules

YK: module imports are declarative, so gives clear dependency order,
effectively a set of jobs, deterministic. Another set of jobs exist...

...modules want to initialize state, using set of promises. dependency
ordering that is opaque to module execution order, benefit of that is we
can have synchronous 1-shot path through module execution...

YK: problem with 2.a...

JM: we've used 2.a. for a long time and it has worked well

YK: ... other things in the dependency graph is opaque, to repair that, we
need toplevel await

AWB: my concern with 2a. only comes up with circular module deps, a set of
dependent modules isn't fully initialized until you circle around, each
module has been given a chance to initialize and execute through entire
body. If you start doing other jobs, somewhere along that path, are there
going to be potential observable....

DH: difference between observable and likely. We shouldn't care about
reflectively being able to observe that things are complete. Ignoring the
reflective stuff, just declarative, initializing these in dep order,
outside of cycles you can't have a problem. Even within a cycle, early
reference to something that hasn't executed yet, but that can happen
synchronously too.

YK: there is a toplevel cycle problem already

MM: I think there is an adjustment to 2a and 2b to avoid cycle problem.
adjustment is strongly-connected cycle is atomic, if we allow
interleavings, only between strongly connected cycles.

AWB: then you'd have to identify these


_discussion about N job module loading -> toplevel await_

DH: _describing the problem with toplevel await and node.js_
... people want to use synchronous functions in module initialization, but
this forks functionality between async/sync variants...
... toplevel await gives you a way to prevent module use before
initialization. in node.js currently people often just race between
initialization and use.

MM: question: node modules is loaded via require? If someone calls require
in a later turn, the module is loaded later. [ everyone confirms ] so
toplevel modules can already be run over multiple turns? [ confirms ]

YK: their concern is that introducing await for require will change the
behavior of require in a confusing way

JM: But it's backward compatibile and not a breaking change, right?


MM: why isn't toplevel await something that can be written already?

YK: you can desugar that already, but they still don't want it

AK: They just don't want the feature.

SP: Bad experience when tried to do this the first time.


YK: they say, once you start using async, everything leaks. And that's true

DH: sounds bad, but there is a reasonable solution. allow toplevel await,
asynchronous loader spec, and node won't use it. any modules that have
toplevel await will be incompatible with node

YK: syntax errors, or run to first `await` and done

DH: they can do whatever they want here, if it becomes popular on the web,
maybe that will change their opinion

MM: If toplevel await is equivalent to something users can write anyway...

YK: I just realized that it is plausible to do what async function does, if
await appears at toplevel the export is a promise

DH: Yes.

- require is zalgo-ish
- may block severely

MM: that to me, disqualifies it. But we're not talking about require, but

DH: all node packages expect to start with toplevel synchronous main and

MM: would expect to interface between two systems, what you obtain is a
require immediately returns

DH: two things that you want for evolutionary path: require an es6 module
that awaits, thing you get back is a promise rather than module. Other part
is an alternative entry point for node: execution semantics at toplevel is
es6 loader program, everything runs through async pipeline, with imports
instead of require

YK: await, import at toplevel could trigger that

DH: maybe inferred rather than opt-in

MM: i don't see how this forces you to require as suspension point for

YK: browser does not want require that sometimes returns value, sometimes
promise. legacy purposes, require returns value.

MM: require has to return what the required module exports

DH: could say: all ES6 modules provide a promise

- Agreement on 2A semantics

2A: Modules execute in the order that they appear textually (same order as
ES6 semantics), but may run across multiple turns.

Moving on.

DH: Need stage 0 for  module metadata

MM: there's a defacto spec in JS: source maps. very specific about what
type of information is mappable. I think this corresponds to

( discussion of import.context )
EF: why import and not export?
(module would be better, but it isn't a keyword)

DH: import.context.lineno, callno?

MM: my point is: if template strings actually created a sourcemap on the
template object, as part of the extended definition, you'd have all the
information by that mechanism, including where the individual thing in the

DH: the competition here is __filename, __dirname, etc. import.context
ergonomics is pretty close, are you talking about something worse?

MM: there is an overlap of functionality with sourcemaps and template
strings -- we should coordinate these.

( question about this exposing a new execution context for module system )

DH: this was always the case with modules.

MM: can't you just create an error, throw and catch it to get the
information for the filename, line, etc. how is the info on import.context

CP: just one concern about import.context compared to `import local from
this module;` proposal, we need a new way/channel to ask loader for such as
information, before it was just a synthetic module that relying on the
loader semantics to do the bindings.

_extended discussion about what information would be stored on
import.context -- is it source name, dir name? or is this too

Dynamic Relative Loading

- Dynamically load a relative module when it's only needed rarely:

// lib/index.js
configButton.onclick = async function() {
  // corresponds to: `import { readFile, writeFile } from 'fs';`
  let { readFile, writeFile } = await import.named('fs');
  // corresponds to: `import config from './config.js';`
  let config = await import('./config.js');
  // ...

DH: Dynamic scope tricks you into thinking that you can abstract normally
(say, by moving outside), but you can't

Need: static syntax to communicate information so that we can dfkjnsdkfbjv

_discussion about import(...) and import.named(...) being meta operators_

AWB: make it not an operator: meta property whose value is a closure

MM: could be closed over the data from import.context

_discussion about ambiguity of syntax_

DH: syntax needs work, not complete/final

MS: because dynamic, needs a new API. Don't like the properties on

DH: _re-explains everything that lead to current design_

_Discussion re: `import(...`_

DH: "out of band" in a subexpression and need additional data

AK: Assumed import dynamically, methods on a loader instance?

DH: Missing ability to do relative dynamic loading, needs context otherwise
need to write information in your code about where the file lives.

AK: need some syntax that says "where am i?"

DH: we want the smallest number of constructs, there is benefit to users
for this. However, inband vs. outband is real ergonomics issue. Ability to
correspond syntatic forms between declarative and imperative forms has value

DH: Moving on. Need global APIs here, reflective API for dynically creating
a module instance. I want Reflect.Module (or something living under
Reflect), DD wants...

tl;dr: Spec defines a module namespace exotic object, need a way to create
these. Custom loaders need to make these.

AWB: can other modules import those? [ others say yes]

DH: reflective vs. source text module objects...

- Module Records, not Module Namespace Exotic Object
- need something for that
- needs to go somewhere
- DD says WHATWG shouldn't be monkey patching onto Reflect object
- Loader spec lives on a bridge
- Not specific to WhatWG
- Belongs in Reflect


MM: _talking about `System`_

DH: This will block stages of Loader.

AK/DH: Milestone 0, not Stage 0

DH: milestone 0 doesn't depend on this syntax, but milestone 1 does, and we
don't want to hold that up, so people can start building the ecosystem

#### Conclusion/Resolution

- Stage 0 granted for dynamic relative loading
- Module Record thing goes in Reflect, full-stop. ("Reflect.Module",
- `Reflect.Loader`, `Reflect.Module`
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list