March 28 meeting notes

Waldemar Horwat
Wed Mar 28 17:42:54 PDT 2012
https://mail.mozilla.org/pipermail/es-discuss/2012-March/021872.html
Here are my rough notes from today's meeting.

    Waldemar

-----
IPR discussion
Intel changed their ECMAScript patent declaration to RANDZ.
Now they wonder why no one else made a RANDZ declaration.
Istvan described the history.
Mozilla is also unhappy with the current state of affairs.  Even
though this instance turned out well, it shows the potential for
problems.
Lots more IPR discussion

Rick Hudson, Stephan Herhut:  River Trail proposal
Proposal will appear on wiki shortly.
Deterministic, except for things such as array reduction order if the
reduction operation is nonassociative.
Parallel arrays are immutable.
Various parallel methods take kernel functions to operate on subcomponents.
MarkM: Are the requirements on the kernel functions to allow them to
be optimized well-defined?
Rick: Yes

var a = new ParallelArray(...)
var b = a.map(function(val) {return val+1;});
Allen: This can be done today sequentially by replacing ParallelArray
with Array.

var b = a.combine(function(i) {return this.get(i)+1;});
var sum = a.reduce(function(a, b) {return a+b;});

Competitors:
OpenCL: GPUs do poor job of context-switching.
WebCL: Too many things undefined.
Browser-provided webworkers (task parallelism).

Waldemar: Can the kernels do nested parallel operations, such as
what's needed for a matrix multiply?
Rick: Yes
Waldemar: What data types can you use?
Rick: This builds on the typed array work.

Some desire for not having too many array times.  Can we unify
ParallelArray with Array?
DaveH: No. Holes alone cause too much of a semantic dissonance.
Waldemar: Would like to unify ParallelArray with typed arrays.
DaveH: No, because ParallelArrays can hold objects and typed arrays can't.
Waldemar: Why not?

Discussion back to knowing which kernels can be optimized.
DaveH, MarkM: Nondeterministic performance degradation is preferable
to nondenterministic refusal to run the code.  This leaves
implementations space to grow.
What about throwing exceptions only for functions that can never be
optimized because they mutate state?

Waldemar:  Is this optimized?  (Note that there are several different
issues here.)
let y = ...;
function f(x) {return x+y;}
a.map(f)

Note that merely reading mutable state is not necessarily a cause for
deoptimization because parallel functions don't run in parallel with
other code, so that state stays fixed for the duration of the parallel
operation.

Allen: Concerned about every closure carrying along sufficient
information to do the kind of abstract interpretation needed to
optimize it as a ParallelArray kernel.
Allen's issue summary:
- Do we want to do this?
- If so, how do we structure the activity (separate standard or part
of ESnext or ESnextnext)?
- Data parallelism or parallelism in general?
Rick: Our goal is to get it into browsers.
Debate about whether to do this for ES6 or ES7.
Brendan, DaveH: Let's just do the work.  The browsers can ship it when
it's ready, regardless of when the standard becomes official.  Need to
get new features user-tested anyway.
Structurally this will part of the mainline ECMAScript work
(es-discuss + meetings), not in separate meetings as was done with
internationalization.

Allen's spec status.

Olivier:  Concerns about latency issues related to module fetches
blocking.  Multiple script tags can fetch their scripts concurrently;
modules have latency problems such as:
<script src=A.js>
<script src=B.js>
<script src=C.js>
vs.
<script src=C.js>
where C.js is:
module A at "A.js"
module B at "B.js"
// use A and B

Alex:  Have modules block document.write.

Long debate about asynchronous loading approaches.

Olivier:  To get better latency, you can make your first module load
simple, but after that you'll need to use the AMD syntax again.
DaveH: Change the HTML semantics.
Alex: Evaluate the outer module asynchronously in script blocks such
as the one below, because there is no non-module code after the
module:
<script>
module M {
  module A at "A.js"
  ...
}
</script>

Olivier: This will error out if followed out by the otherwise correct:
<script>
M.foo();
</script>

DaveH proposal: Bifurcate grammar so that scripts (whether in <script>
tags or in files included from those) cannot contain static module
load statements, not even in syntactically nested modules.  Modules
can include such statements but can only be parsed via dynamic loads.
<script>
System.load("interp.js", function(m) {...});
</script>

interp.js contains:
module stack = "stack.js";
export function evaluate(...) {...}

stack.js contains:
export class Stack {...}

The body of an eval would be treated like a script body, not a module
body.  This avoids the tarpit of dealing with synchronous i/o in eval.


For-of design variants:
Variant 1:
import keys from "@iter"
for let k of keys(o)

Variant 2:
for own (let k in o)

Current way:
Object.keys(o).forEach(function(...){...});

Picked variant 1.

DaveH: The people want Array.of and Array.from and don't want to wait
for the ... syntax.
Array.of(a, b, c) ≡ [a, b, c]
Array.from(a) ≡ [... a]

Brendan: Disallow initializer in:
for (var i = x in o)
MarkM: OK, as long as Brendan is the first penguin through the ice hole.
Mozilla will take it out.

Brendan's arrow proposal:
ArrowFormalParams_opt -> Block_opt
ArrowFormalParams_opt => AssignmentExpr

ArrowFormalParams:
(FPL)
(this Initialiser_opt, FPL)  // Makes this dynamic
(this Initialiser_opt)       // Makes this dynamic
Identifier

Brendan:  -> and => both use static this.
DaveH:    -> defaults to dynamic this, => defaults to static this
Debate about Tennent Correspondence Principle and to what extent this complies.

ArrowFormalParams is actually parsed as the cover grammar:
(CommaExpression)
with later semantic restrictions on what the CommaExpression can
actually contain.

Waldemar:  A lot of problems that are individually nonfatal but too
much in combination.
1. Two different arrows is confusing.  Will keep using the wrong one
and get weird results.  Examples:
  -> {a:b}  // intended to return an object literal, instead has a
labeled expression
  -> {}     // intended to return an empty object, instead returns undefined
  => {}     // intended to return undefined, instead returns an empty object
2. Having both dynamic and static this options is overkill.
3. TCP hazards
4. Cover grammar introduces a lot of spec complexity.
5. Different 'this' defaults in DaveH's variant of the proposal

Wild debate.
Poll of who objects to which problem in the proposal:
1.  AWB, MM, AR, AR, LH, DC, WH, DH
2.  AWB, MM, AR, AR, LH, BE, DC, WH, DH
3.  AR, AR, LH, DC, BE
5.  AWB, MM, AR, AR, LH, BE, DC, WH, DH

If we choose only one arrow, which is it?  Flow of debate assumed it's
=>, with a do expression used to place statements there if needed.
Luke, Waldemar:  Use only one arrow, but allow either a block or an
expression there.  If it starts with a {, it's always a block.
MarkM: What about => function foo(){}?
No issue there; it's a function expression.  Only => { starts a statement.

MarkM:  => assignment cannot be TCP due to yield.
Debate over meaning of TCP.

Some people have changed camps.  The ones above are from the original poll.
Confusion about the meaning of poll polarity on item 3.
New results:
WH, AWB, MM:  object to 1, 2, 5; want TCP
BE, DH, AR, AR, LH, OH:  object to 1, 2, 5; don't want TCP
DC:  object to 2, 5; don't want TCP

DC switched to middle camp.
AWB, WH, MM prefer to keep TCP but are ok with switching to middle camp.

Consensus on:
- Have only one arrow, namely =>
- this is always static.  No provision for dynamic this.
- Other than the treatment of this, the function behaves like a normal
function.  return, break, etc. behave as though the function body were
in a function(...){...}.

To be discussed later:
The thing that comes after the arrow:
1. Always an expression (possibly a do expression)?
2. A block if it starts with {, otherwise an expression.
More information about the es-discuss mailing list