Ecma/TC39 Meeting – Mar 13 2013

link March 13 2013 Meeting Notes

John Neumann (JN), Norbert Lindenberg (NL), Allen Wirfs-Brock (AWB), Rick Waldron (RW), Waldemar Horwat (WH), Eric Ferraiuolo (EF), Erik Arvidsson (EA), Luke Hoban (LH), Matt Sweeney (MS), Doug Crockford (DC), Yehuda Katz (YK), Brendan Eich (BE), Sam Tobin-Hochstadt (STH), Alex Russell (AR), Dave Herman (DH), Adam Klein (AK), Bernd Mathiske (BM), John Pampuch (JP), Avik Chaudhuri (AC), Edward O'Connor (EOC), Rick Hudson (RH), Andreas Rossberg (ARB), Rafeal Weinstein (RWN), Mark Miller (MM), Reid Burke (RB), Edward Yang (EY), Dan Stefan (DS),

link 4.14 Make new Date(dateObj)

(Presented by Allen Wirfs-Brock)

See: https://bugs.ecmascript.org/show_bug.cgi?id=1257

AWB: Propose to fix this by spec'ing the Date constructor to special case date object arguments and produce an accurate copy of the date object.

DC: Produces a clone?

AWB: Yes.

DC: a Issues with toString?

AWB: No

NL: Bug mixes ES5/ES6 spec language: DefaultValue/DateValue?

AWB: Not an issue

link Conclusion/Resolution

  • When date object is passed to the Date constructor, it makes an accurate copy of the date object.

link 4.4 Spec Update

(Presented by Allen Wirfs-Brock)

http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

link RegExp global, ignoreCase, multiline, source, sticky are now prototype accessor properties rather than instance own data properties.

AWB: WH's question, "why are the flags now accessor properties?" (re: RegExp global, ignoreCase, multiline, source, sticky) is necessary to support a web compatible "compile" method. The web reality takes an existing instance and reinitializes a new instance.

MM: SES doesn't whitelist "compile", but could we specify "compile" to be SES whitelistable. Freeze, no longer modifiable by compile

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
var re = /abc/;
re.compile("changed");
console.log(re);
// > /changed/
Object.freeze(re);
re.compile("again");
console.log(re);
// > /again/
// oops

DC: What is the history of "compile"?

AWB: Not sure, but I believe it was JScript

link ArrayBuffer and TypedArray object length no longer restricted to 2^32 limit

DH: We should talk offline about making sure this is future proof

MM: is the new length 2^53? If it goes over, there will be a length that can't be represented

...Mixed discussion about the length limitations of existing arrays.

AWB: Isn't really an issue, just allows the length of arrays to be sufficiently large. I believe this is the future proof solution

ARB: Is it inconceivable that you might want to create a TypedArray backed by a large mapped memory?

DH: Not inconceivable. ...Regardless of whether you want something 2^53 or above

YK: Agree with Allen that this is probably sufficient.

DH/AR: (brief discussion about ownership of TypedArray spec)

AWB: Can't use the same methods as Array, because they use 2^32 length.

MM: And are all generic, so really work on "array likes"

AWB: It's not clear that they should work and it may not make sense to have these methods. There are possible solutions

WH: An example of non backwards compatible?

MM: Sparse array that's not populated up to the limit and push on it? What happens?

WH: Calls ToUint32 on it?

AWB: Yes

WH: Doesn't consider those array like?

AWB: Array spec, gets and sets, does its own Uint32 ...Need to look at each of these methods and see what can be done to make these compatible.

BE/AWB: (mixed discussion about historic compatibility issues)

BE: We can try it and the first sign of trouble, back off.

MM/AWB/BE: (agreement)

WH: The main use I see of ToUint32 is to call it on the existing length. Indices passed in as arguments are generally processed via ToInteger. As such, getting rid of the ToUint32 in generic Array methods applied to non-Array objects shouldn't present much difficulty (when they're applied to Array objects the change would be invisible because Array length can't reach 2^32).

AWB: But it doesn't have to be an array ...We should move on.

link 4.5 Private Symbols, WeakMaps, and Relationships

(Presented by Mark Miller)

Slides (PDF, will prompt download): http://wiki.ecmascript.org/lib/exe/fetch.php?id=meetings%3Ameeting_mar_12_2013&cache=cache&media=meetings:relationships.pdf

MM: Concerned about the overlap in functionality between WeakMaps and private Symbols.

...WeakMap named with the word "Map" inverts the thinking.

...Allen noted that WeakMaps are about a Relationship, between two objects.

Legend:

base is key field is map

(Slide 2)


"Map" inverts thinking (the use of ">>" signifies the that the item on the LEFT is usually better for most purposes then the RIGHT)

Syntax: base@field >> map.get(key) ...Describes the relationship more accurately

GC: impl(base)[field] >> impl(map)[key] ...A better implementation on the LEFT, despite most implementing the RIGHT

Lookup: Inherited props >> own props

Intuition: Relationship >> Symbol >> Map

Unique Symbols ok.


STH: Weak hash tables are found in programming languages and people want them in JS, but they historically fall in the RIGHT. Why can't we declare victory and go home?

MM: I feel like we can declare victory, but more work to do.

WH: Let's avoid a meta discussion.

(Slide 3)


ES6 Encapsulation Mechanisms

Closures hide lexical state (ES5)

Modules hide non-exports

Direct Proxies hide handler and target

WeakMaps hide keys, do rights-amplification

Private Symbols


(Slide 4)


GC: base@field = value ...Not discoverable given "base". Have to have both "base" and "field" to get value.

Abstract heap maps(base, field) => value base and field reachable -> value reachable

...Introduces an "and" into the previously only "or" GC map

Obvious representations:

  1. impl(base)[field] => value better when field lives longer ...When base dies early, it will take the association with it, by regular GC and without needing ephemeral

  2. impl(field)[base] => value better when base lives longer ...When field dies earlier, it will take the association with it, by regular GC and without needing ephemeral


(Slide 5)


GC by use case

When base is known to live longer Just use a map (per Yehuda)

oo private field is known to live longer. Just use representation #1

Most remaining WeakMap use cases would do better with representation #1 (untested claim)

(From a GC perspective)


MM: The GC cost is significant. If you chose the wrong implementation, every object that gets trademarked is retained by the WeakMap until you invoke the ephemeron collection algorithm.

ARB: It's worse in v8 because it has an incremental GC that currently can only run that on full collections

MM: w/r to normal access, I believe it's a wash

AWB: I don't think it's a wash, case 1 requires an index, case 2 requires a hash code

(Slide 6)


GC by use case

Only need ephemeron collection when

  • you guessed wrong relative longevity
  • you care about the memory pressure

Felix's O(N) algorithm is affordable with inverted representation

Examples: Membranes


MM: Membranes are an example where you still need the ephemeron collection algorithm

b is base object f is field

L is left side R is right side

T is target P is proxy

(Slide 7)


Transparency vs Privacy ...Membrane:

Test: bL@fL = vL bR@fR === vR

...see slide


[Whiteboard Example, get image from Sam]

MM: Propose changing the name of WeakMap and changing the way we specify and describe them for implementors to think about.

AWB: Last meeting, we discussed cases... eg. when you invoke a method whose this object expects access to the private state, but it receives a proxy, it will break. I believe the solution might solve the problem

YK: |this| binding issues are orthogonal to this issue

BE: (Agree)

MM: (refutes)

WH: I challenge on this, there is a claim that we don't need private symbols and that they're broken, but we need to do things that private symbols are for. So why can't private symbols work the same way?

MM: This accomplishes things that we needed private symbols to accomplish, if you want to propose changing the name of w

WH: I want to see common uses of private symbols and how you would replace them.

MM: I haven't shown the broken solutions...

STH: I think that would've been much more helpful then showing what works today and that you wouldn't change.

MM: I believe this is an acid test to prove the transparency

WH: Implement private symbols in terms of whatever you're proposing.

MM: fT is a private symbol

WH: ...

MM: I'm trying to answer your question

WH: What would I need to do differently and why, using your glorified new approach.

MM: In the expansion of a class that uses a private symbol, for each declared private instance variable, there will be a private symbol per instance variable.

WH: I think you'll need to write it down.

MM: (describes semantics, based on Slide 8)

WH: You're saying private symbols work if they adopt this semantics

WH/STH: What are the changes?

STH:

  1. There is no trapping on writes and reads of proxies, passes through
  2. proxy a private symbol and write sets and gets, trapped to the handler that has that private symbol.

...In Mark's defense, this is a substantial change to how we think about private symbols

AWB: It's a new type of access on an object, with a new type of state. A new, different operation with separate behaviors

YK: Will the vast majority of JavaScript programmers have to understand this? This is the most important question for me

ARB: ...?

TVC: Don't need to change proxies in anyway

YK: Not actually my concern

STH: Need to think of these as something more then properties

MM: Thinking of them as properties is what caused me to gravitate towards addressing

(Slide 9)


Desugaring Private Relationships

1
2
base@field base@field = value
field.get(base) field.set(base, value)

(Slide 10)


What about symbols and strings?

1
2
3
4
5
6
7
8
9
10
11
12
base@field base@field = value
-field.get(base)- -field.set(base, value)-
field[@geti](base) field[@seti](base, value)
String.prototype[@geti] = function(base) {
return base[this];
};
String.prototype[@seti] = function(base, value) {
base[this] = value;
};

MM: Don't want to use string name "get" and "set" for the invocation, I want to use a symbol

WH: What is the implementation of @geti?

MM: The semantics of WeakMap's get, with exception that if the key isn't found, it tries the object the key inherits from (i.e., follows the prototype chain) until it finds a key or fails. In other words, it implements the inheritance semantics we expect of accessing properties. Given the use of representation #1, this can reuse the existing optimizations for inherited property lookup.

...?

MM: Private symbols, not discoverable

AWB: You've transformed it into a alternate MOP level operation, but you could've transformed it into a new MOP level operation... (missed this before Waldemar interrupted)

WH: This was my proposal 3 years ago...

MM: Explanation...

WH: Not allowing these things to have normal descriptor rules is a bug.

STH: Exactly, the existing proposal reuses the mental model of JavaScript programmers that we should continue to use. Same is true for encapsulation at the property level and GC mappings.

AWB: If you want true privacy

WH: ... You need

AWB: You can't proxy anything that has private state. Cant proxy any built-ins, or anything with private symbols.

BE: Asking TVC to address Waldemar's concern

WH: When the issue of membranes vs private symbols first came up, I showed an inversion approach, instead of asking the object's proxy to look up, you'd ask the private symbol's proxy. This had been intended to solve the proxy privacy leak problem (don't want object proxies to see the objects' private state), but it's essentially the same issue and solution.

TVC: Having property access by the private symbol

STH: Mark is proposing something that has similar semantics, without a new meta operation, but pays for that by making it less like true properties

WH: So which is it?

MM: If the definition of WeakMaps is something you "stick things into", then the answer is private symbols.

WH: Please show an example how we'd actually use this and how it would interact with a proxy

(break for lunch)

MM:

private is a pseudo-syntax mechanism

1
2
3
4
5
6
7
8
9
10
class Point {
constructor(private x, private y) {}
toString() {
return `<${this@x}, ${this@y}>`;
}
add(point) {
return Point(this@x + point@x, this@y + point@y);
}
}

Desugars to...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let Point = (function() {
const x = Rel();
const y = Rel();
function Point(x, y) {
this@x = x;
this@y = y;
}
Point.prototype = {
toString() {
return `<${this@x}, ${this@y}>`;
}
add(point) {
return Point(this@x + point@x, this@y + point@y);
}
};
})();

YK: If you're calling add through a proxy?

MM: If you're calling one Point proxy from another Point proxy, the

YK: Use case, I want the |this| binding to be the proxy

MM: Call add() method on a proxy of a Point If the right operand is a proxy,

BM: a proxy to a point doesn't have an x

AWB: Specifically, a proxy to a point isn't registered in x

...Concern: if you had done toString simply as a get access

YK/STH: If Proxies are going to fit into the language, with any sort of concept of private state, then we need to solve the problem, and this doesn't solve the problem.

MM: Use membranes.

WH: If you come up against this problem many times and each time the answer is membranes, then we need to add membranes, not proxies.

General Agreement.

STH: Until we decide which side of the solution we want: either transparently proxying objects with private state should work, or private state can indicate that something is a genuine not-a-proxy instance of an abstraction (such as Date), then we can't possible have a solution.

YK: Hiding implementation details that manage private state that can't be proxies.

AWB: Virtual object vs Caretaker

BE: Not going to make unstratified traps

YK: only need a small amount of traps: get and set

...Can't go down this road.

(going in circles now)

BM: Notes that the next logical step is interfaces, where you define an interface and proxies implement against this.

BE: Can't apply an interface to already born objects.

BM: if you pre-plan that the object is inline with the interface then security is under control

BE: We should defer private symbols

AWB: If we do that, then there is no private branding on the object

STH: Doesn't solve the problem for "what does proxy for dates do"?

More discussion about the general flaw of proxies wherein... objects that have some form of internally implemented "private" state cannot be observed and therefore not subject to trapping.

MM: Can we agree that transparency through membranes is a requirement?

AWB/STH/YK: Agree its important, but there are a lot of requirements.

MM: A champion group should go and solve these problems. Retaining WeakMaps, deferring private symbols very closely matches the proposal.

STH: ...

MM: Just want to consolidate the issues

STH: Bad idea to postpone WeakMaps, which useful and are already shipping in browsers. Bad idea to postpone anything based on a particular issue with Proxies. A separate issue with regard to the design of private symbols. None of these are solved by adding "@" to represent a WeakMap.

WH: It seems like @ for WeakMap makes sense

BE: Too much for ES6

MM: Regardless of the syntax/API, the slides show that we should encourage implementers to hang the state off the key, not the base.

AWB: The WeakMap abstraction we have is fine as is. If an implementation wants to invert its handling of keys and the map, then that's fine too.

WH: (some comment about private state?)

STH: That's not related

AWB: (re-iterates)

MM: The inverted representation is the better one.

YK: So, what is your proposal?

MM:

  • My proposal is the private symbols get postponed to ES7
  • WeakMap gets renamed to reflect the inverted thinking
  • If we adopt the @ syntax in ES6, I want to be able to use a WeakMap on the right side

...Don't care so much about the renaming, but feel that it could add clarity to the feature

RW: (Disagree based on experience teaching the concept)

WH: no consensus on class without private symbols

MM: Rick, can you find the history of this?

RW: (recounts two meetings where Waldemar was not present, but a general consensus existing with the understanding that Waldemar would still have something to say. At Northeasten, Allen presented @-names, in which Waldemar found to sufficiently meet his privacy requirement for classes)

...Discussion around class private state as a whole.

BE: We need to synthesize what's going into ES6. Waldemar claims this must include some way of adding class private state.

STH: I would like to stop this conversation and allow myself time to think about this.

BE: Done.

link Conclusion/Resolution

  • Sam, Mark and Allen to work on "relationships" and varied representation in ES6.

link 4.3 Proxy

BE: We've had prototype implementations for some time, we made it through the change of API. We use them extensively.

link 4.16 Current Status of ES6

(Presented by Luke Hoban)

Spreadsheet: http://sdrv.ms/Z9pQxs

AWB: Based on this review, we should shoot for December 2014

Discussion of time tables for completed spec reviews

NL: Also need to look at progress on implementations.

NL: Concerned about impact on Internationalization API 2.0 – need to evaluate whether to base on ES5 or slip to December 2014.

link Conclusion/Resolution

  • November 2013, Final review draft
  • June 2014, Editorially complete (STH: we said June in the meeting, but July makes more sense, since we don't have to submit to the GA until September, IIUC)
  • December 2014, ECMA approval

link 4.7 Runtime costs of the override mistake

(Presented by Mark Miller)

Override Mistake http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake

(Request spreadsheet)

RW: Would like to see the most minimal piece of code required to illustrate the operation, measured by executing the operation in several rounds with MAX number of executions calculated to a mean value. Also, there is use of an in operation which will skew the results between Firefox (a bit faster) and Chrome (slow)

WH: I'd like to see comparisons of non-frozen vs. frozen to see whether the two order of magnitude Chrome slowdown is caused by freezing or inherent slowness of push and pop.

Varying, lengthy discussions around SES techniques and the implications of the override mistake.

Non-issue for code that doesn't freeze.

link Conclusion/Resolution

  • Investigate instrumentation when silently fails non-writable prototype properties.

Ecma/TC39 Meeting – Mar 12 2013

link March 12 2013 Meeting Notes

John Neumann (JN), Norbert Lindenberg (NL), Allen Wirfs-Brock (AWB), Rick Waldron (RW), Waldemar Horwat (WH), Eric Ferraiuolo (EF), Erik Arvidsson (EA), Luke Hoban (LH), Matt Sweeney (MS), Doug Crockford (DC), Yehuda Katz (YK), Brendan Eich (BE), Sam Tobin-Hochstadt (STH), Alex Russell (AR), Dave Herman (DH), Adam Klein (AK), Edward Yang (EY), Dan Stefan (DS), Bernd Mathiske (BM), John Pampuch (JP), Avik Chaudhuri (AC), Edward O'Connor (EOC), Rick Hudson (RH), Andreas Rossberg (ARB), Rafeal Weinstein (RWN), Mark Miller (MM)

link Opening

link Introduction

link Logistics

link Adoption of Agenda

Mixed discussion regarding scheduling over the course of the 3 days.

Approved.

link Approval of January 2013 Meeting Notes

Approved.

link Adobe

JP: Here to help accelerate the ES6 spec, positive motivation. Excited about Modules, concurrency, debugging and profiling specifications.

BM: Background as trained language designers and implementors and here to help.

JP: Also excited about asm.js

BM: Not sure about the spec status/prospects of asm.js.

Edit (2013-03-22) http://blogs.adobe.com/standards/2013/03/21/adobes-ecma-tc-39-involvement

link 4.9 JSON, IETF changes

(Presented by DC Crockford)

Currently, JSON is an RFC, informational, the IETF version will be an internet standard and there is a minor correction that affects ECMAScript.

The use of "should" in 15.12.2

AR: What is the motivation of the change?

DC: The change involves the mistake of using "should" w/r to multiple same-named keys error. Multiple same-name keys are invalid and must throw an error (vs. "should" throw an error)

LH: This is a breaking change

DH: The worst being the use case of multiple, same-named keys as comments

DC: That's stupid

YK: That's based on on your recommendation to use a keyed entry as a comment, so people naturally used the same key, knowing they'd be ignored.

DC: I would certainly never recommend that practice

YK: It was a side-effect

AR: Which key is used now?

AWB: The last one wins.

AR: Is that the root of the security vector?

DC: Not in ES, but in other encodings

AR: Order matters, unescaped content that follows...

DC: The current spec says "[they should not]", but will say "[they must now]"

YK: Let's define an ordering and make it cryptographically secure.

DC: (recapping to Mark Miller, who just arrived)

MM: You can't do that. (laughs)

MM: You can't change "should" to "must"

YK: Agreed, you cannot change JSON, there are too many JSON documents in existence.

MM: Agreed.

AR: It's possible to ignore this change?

DC: Yes

DH: Then why are we creating a dead letter?

MM: ES has a grammatical specification for validating and parsing JSON. Anything that is not conformant JSON, would not parse. This change loses that property.

DC: Or we don't change the spec

MM: The way that you properly reject our favorite fixes, I think you should apply to your favorite fixes

DC: I'll consider that

AR: There is considerable opposition to this change

DC: Two choices...

  1. Make it an error
  2. Continue to take the last one

DC: Decoders have license to do what they want with non-conformant material. Encoders must be conferment to new changes.

MM: Our current encoder conforms...

AWB: I don't think it does... reviver/replacer

MM: No, can only apply objects instead of the original objects.

AR: Did not realize the production/consumption distinction of this change.

WH: Supports this change. ECMAScript is already conformant because it never generates duplicate keys.

MM: With this change ECMAScript would have two unappealing choices: A. No longer be a validating parser (i.e. a parser that doesn't allow any optional syntax or extensions, even though extensions are permitted by the JSON spec). B. Do a breaking change by throwing errors when seeing duplicates when parsing.

link Conclusion/Resolution

  • Revisit this, after DC has made a final decision.
  • FTR: Majority opposition, no consensus.

link 4.12 StopIteration/Generator

(Presented by Dave Herman)

https://github.com/dherman/iteration-protocols

DH: ...Confirms that there is lack of understanding for Generator "instances"

MM: Clarify terminology

DH: Generator objects are instances of Iterators, in that they have a next method. The current design is based on a thrown StopIteration

C#, Java, Python apis for comparison.

My opinion, a single method is win.

Concrete proposal:

  • The benefit of a single method
  • Not based on exceptions
  • Compatible with Generator semantics

Iterator API object has a single method:

1
2
3
4
{
next() -> { done: false , value: any }
| { done: true[, value: any] }
}

b/c generators can return an argument, if you're using a return value

1
2
3
4
function* f() {
yield 1;
return 2;
}

for for-of this doesn't matter, but for libs like q, task.js this is useful for pause and resume with value

If we didn't care, the result value can be omitted

This API was pleasant to write and works nicely with existing idioms

MM: Requires allocation for every iteration?

DH: Yes, will still need the object allocation, but

WH: Does next return a fresh object? or can reuse the same?

DH: Can reuse

AWB: For every iterator in the spec, we need to specify a fresh or reused object?

DH: Yes.

YK: The current API, able to do yield ...returns a promise...

DH: Can still do that, this change is internal and w/r to performance, this should be highly optimizable.

AWB: Anything that uses a method based implementation, will be more optimizable through calls vs exception.

DH: I've never seen an iterator API that didn't have some performance issues

AWB: (refutes) Any method based approach can be better optimized over exception based approaches.

DH: I don't have a solid performance story, but the feedback I'm getting is that there is negative concern about the StopIteration approach, whereas this approach mitigates these concerns. Issues arise when dealing with multiple iterators

WH: If you try throwing StopIteration across iterators, it will be caught

AWB: Or it won't

EA: Surprising: If any function throws a StopIteration, it will jump out of the for-of.

AWB: I noticed this in the examples shown in the github repo

WH: Why I'm in favor... Throwing StopIteration across places where no iterators exist and if code is refactored so that an iterator is present, you'll experience unexpected behavior. (This suffers from the same capture flaws as Lisp's old dynamic scoping.)

LH: When we last talked about this, we whiteboarded the priority order. for-of is the primary case, generator authoring is the secondary case. Cases affected by this: direct API consumption as third and direct API authoring is fourth

If we're really sure the engines will do the work to optimize these things?

A. will this slow down implementation? B. won't be willing to implement due to poor performance?

AR: No implementation wants to ship something that will potentially be slow

LH: Of course, but StopIteration has to go.

MM: One allocation per loop

WH: So is this

MM: Only if you reuse the record

LH/WH: Of course and that's what you want

MM: Then, as Allen said we need to specify this

DH: My inclination would be to use a fresh object each time

AWB: ...you know the first time, because it's the first time that next is called,

MM: My proposal is that you provide stop token as a parameter of next(stop), every time. next(stop) would return either the next value or the stop token.

DH: (clarifying) "iteration" is one time around the loop. "loop" is the entire the operation.

WH: It's possible for next(stop) to cause havoc from one iteration to another by caching one next call's stop parameter and returning it from a different next call.

[Someone had also presented a variant of the proposal where was a field on the iterator instance instead of an argument to next.] WH: This would create funky failures if, for example, you had an iterator that did a deep traversal of an object tree and said tree happened to include the iterator instance.

MM: In order to not allocate on every iteration, you have specify (???)

MM: A new stop token would be generated per loop.

WH: What's a loop? This gets confusing when you have iteration adaptors.

AWB: If the client passes in the token on next(), then it's the client's burden

MM: Anything that's unforgable, unique, or itself side affectable.

DH: Is there support for Mark's API?

RH: If you use Mark's API, overtime...

MM: My API reuses the object for the iterations of the loop, by passing it back in as an argument to next()

RH: To avoid the cost of allocation?

MM: Yes, but only as a token

EA: You can have a return value in a generator so the object passed in needs to be mutated to include the return value in case of end of iteration.

MM: That is a downside of this proposal, where StopIteration would carry the value.

DH: (examples of the two proposals)

Dave's

1
2
3
4
{
next() -> { done: false , value: any }
| { done: true[, value: any] }
}

Marks's

1
2
3
{
next(X) -> any | X
}

AWB: (suggests an alternative: pass an object to next, on which next sets the result)

STH: ...is hostile to implementors and user code.

ARB: That's the C-style of doing it.

WH: Suppose the iterator takes an object and returns all the properties, but calls on itself?

DH: Mark's proposal is broken, because it doesn't work with return values of generators.

MM: Agreed.

DH: Don't think that we're approaching consensus, but don't let your idea of perfect cloud judgement. I'm asking engine implementors if this is appealing. The concern over StopIteration is real.

AWB: This is certainly better then the current plan of record

AR: Agree.

BM, JP, AC: Agree

BM: This is also future proof and works well with concurrency and the semantics are sound. It's also easy to implement and optimize.

AWB: All spec iterators/generators must specify a reused iterator or fresh

MM: (further support for AWB's claim)

DH: Not sure if we're trading short term wins for long term losses. Are there long terms

ARB: There is another secondary effect that it encourages better GC

AWB: This shouldn't be a problem for a good GC

MM: I'm really only concerned about the loop aspect

AR: We have the tools to work with hot loops

WH: Alex's point about the escape valve is key

DH: Not discounting the needs of the developers/user code. The method API is appealing, vs. StopIteration

RW: Agree.

DH: (Shows example of C#)

AWB: The third use case that Luke gave, using an iterator and the fourth use case, creating an iterator. ...This API is more complex for user code ...More ways for client code to go wrong

BM: Disagree, this is a safer.

DH: Don't get out of sync. Argue that the Java and C# API are too error prone.

BM: Agree, this is actually superior to the Java and C# APIs

ARB: This is actually the path you'd want in typed languages, minimizes state space

DH: I want to see a better overall interface for iterators and generators, without jeopardizing the acceptance.

MM: In favor of this API, if the implementors are not objecting. Although I don't like the API itself.

DH: Agree, I prefer the pure, stateless proposal

AWB: If an object is passed an argument, the object is used as the value bucket.

DH: Still mutates the object

AWB: But it mutates an object that you've explicitly provided

BM: The issue is not the allocation, but that you have to go to heap at all.

ARB: If you do this pre-allocation thing, it might be observable

BM: But that's the case either way

DH: Is the mutable version going to harm optimization?

ARB: Yes: the object may be shared, in which case mutation may become observable from the distance, and cannot be optimized away

RH: If the object being mutated escapes to an old mutation, this kills potential optimizations.

DH: Seems like consensus on the pure, stateless version of this:

1
2
3
4
{
next() -> { done: false , value: any }
| { done: true[, value: any] }
}

JP: "more" vs. "done"?

(can discuss further)

link Conclusion/Resolution

  • Rough agreement (between those present) on pure, stateless version of:
1
2
3
4
{
next() -> { done: false , value: any }
| { done: true[, value: any] }
}

...To replace StopIteration

  • Always has an own property called "value":
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var i1 = (function *f() {
return;
})();
"value" in i1.next();
var i2 = (function *g() {
})();
"value" in i2.next();
var i3 = (function* h() {
return (void 0);
})();
"value" in i3.next();
  • Built-in iterators should be specified as returning a fresh value.
  • See: https://gist.github.com/dherman/5145925
  • Without Brendan, a champion of iterators and generators, don't have full consensus

link 4.2 Modules

(Presented by Dave Herman, Sam Tobin-Hochstadt, Yehuda Katz)

See: https://gist.github.com/wycats/51c96e3adcdb3a68cbc3

Slides (PDF, will prompt download): http://wiki.ecmascript.org/lib/exe/fetch.php?id=meetings%3Ameeting_mar_12_2013&cache=cache&media=meetings:modules-march-2013.pdf

DH: We're committed to making this happen for ES6, it's too important to miss and I'm going to do whatever it takes. Please remember that you can always bring specific issues directly to us (DH, STH, YK).

...Not going to spend time on syntax. Focus on Module loading semantics to address any outstanding issues, spent last two months working with Sam and Yehuda and polling community leaders to get use cases to work with.

Recognize that some use cases may not be covered, but that's ok.

link Module Loading Semantics

...Currently a notion of having a string-name registry

...Move towards having a separate space for module registration

Minimalism - IN Nested Modules - OUT

1
2
3
4
5
6
7
8
9
module "libs/string" {
export function capitalize(str) {
return (make the string capitalized)
};
}
module "app" {
import { capitalize } from "libs/string";
}

The registry corresponds to a Loader which creates a Realm

MM: But you can have more then one Realm

DH: Think of Loader as a virtual "iframe", as a concrete way of describing it. When you create an "iframe", you get a whole new global object with it's own DOM. A Loader creates a "sandbox" global that can share system intrinsics.

The System loader.

1
2
var capitalize = System.get('libs/string').capitalize;
var app = System.get('app').app;

Custom loader:

1
2
3
4
5
6
var sandbox = new Loader({ intrinsics: System });
sandbox.set('app', System.get('app'));
sandbox.get('app') === System.get('app'); // true
sandbox.eval("import { capitalize } from 'app'; capitalize('hi')"); // "Hi"

Acts like a map, .get() will get the module

[Module pipeline diagram]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module name
|
V
normalize
|
V
resolve
|
V
fetch
.
.
V
translate
|
V
link

Produces one of three values:

  • undefined: default linking behavior
  • Module: registers module instance object directly
  • {imports : [ModuleName], execute : (Module ...) -> Module, exports : [String]} : invokes execute to produce module, exports optional

...

link Use Case: Module Paths

1
2
3
4
System.ondemand({
"http://code.jquery.com/jquery-2.4.js": "jquery",
"backbone.js": [ "backbone/events", "backbone/model" ]
});

...is sugar for...

1
2
3
4
5
6
7
8
9
10
11
12
System.resolve = function(path) {
switch (path) {
case "jquery":
return "http://code.jquery.com/jquery-2.4.js";
case "backbone/events":
case "backbone/model":
return {
name: "backbone.js",
type: "script"
};
}
};

MM: This is changing the behavior only at the system Loader?

DH: Yes.

STH: This is the API that several people indicated was important during the last meeting.

link Use Case: ...?

link Use Case: Compile To JS

1
2
3
4
5
6
System.translate = function(src, options) {
if (!options.path.match(/\.coffee$/)) {
return;
}
return CoffeeScript.translate(source);
}

LH: Is this updated on the Wiki?

DH: Will update. Much of the changes are about refining API and making common things easy and most things possible

link Use Case: Custom AMD

Creating custom translations for extensions...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { data: foo } from "text!foo";
```js
System.normalize = function(path) {
if (/^text!/.test(mod)) {
return {
normalized: mod.substring(5) + ".txt",
metadata: { type: "text" }
};
}
// fall-through for default behavior
}
System.translate = function(src, { metadata }) {
if (metadata.type === "text") {
let escaped = escapeText(src);
return `export let data = "${escaped}"`;
}
// fall-through for default behavior
}

WH: Why would you want to do it this strange way (escape text only to then eval it) instead of just letting the text be? [It feels kind of like the folks doing eval("p." + field) instead of p[field]].

DH: (explains James Burke's summary of static asset loading)

link Use Case: Importing Legacy Libraries

(Specifically, not libraries that use CommonJS or AMD, but libraries that mutate the global object)

1
2
3
4
5
6
7
8
9
10
11
12
13
var legacy = [ "jquery", "backbone", "underscore" ];
System.resolve = function(path, options) {
if (legacy.indexOf(path) >= -1) {
return {
name: path, metadata: { type: "legacy" }
};
} else {
return {
name: path, metadata: { type: "es6" }
};
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function extractExports(loader, original) {
var original =
`var exports = {};
(function(window) { ${original}; })(exports);
exports;`
return loader.eval(original);
}
System.link = function(source, options) {
if (options.metadata.type === 'legacy') {
return new Module(extractExports(this, source));
}
// fall-through for default
}

LH: Once we ship this, we want people to start using modules as soon as possible. How?

YK: Realistically, a "plugin" for something like require.js will have to provide an ES6 "shimming" mechanism.

LH: To paraphrase, we're providing the primitives that make the common cases easy to overcome. What about the legacy libraries that won't be brought up to date? Can we provide a simple mechanism?

DH: No, legacy libs that just expose themselves to the global object, without any sort of shimming mechanism are out of reach

LH: Thank you, that's a sufficient answer

link Use Case:

Import AMD style modules and Node style modules. Effectively, ES6 module importing from non-ES6 module.

There is no way to tell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
System.link = function(source, options) {
if (options.metadata.type !== "amd") { return; }
let loader = new Loader();
let [ imports, factory ] = loader.eval(`
let dependencies, factory;
function define(dependencies, factory) {
imports = dependencies;
factory = factory;
}
${source};
[ imports, factory ];
`);
var exportsPosition = imports.indexOf("exports");
imports.splice(exportsPosition, 1);
function execute(...args) {
let exports = {};
args.splice(exportsPosition, 0, [exports]);
factory(...args);
return new Module(exports);
}
return { imports: imports, execute: execute };
};

BM: Could you postulate that exports and

DH: You could but, unrealistic

BM: Could be optimizing for module provider, but not consumer... ...

MM: What does the Module constructor do? DH: Copies the own properties of the given object.

MM: What is the job of the System.link hook?

STH: To go from a piece of JavaScript source code to module instance object, translate is string->string.

WH: Is it a module or Module instance?

DH: Module instance object

Take the source code, all the deps, finds all the exports, links them together.

The link hook can return

  1. undefined for the default behavior
  2. A Module instance, where everything is done and complete
  3. An object, with list of deps and factory function to execute at some later time (eg. when all deps are downloaded and ready)

YK: Explains that a two phase system is required whether you're using node, AMD or anything. Now you can use ES6 provided hook.

BM: Optionally specify the list of exports?

DH: Yes.

Conversation about specific example.

MM: Clarify... noting that the positional args is similar to AMD positional args

DH: Yes.

ARB: No static checking for non-ES6 modules?

DH: Yes, it's a hole that can't be filled if we want interop from AMD->ES6 and ES6->AMD (or node)

ARB: Concern about having two imports, checked and unchecked. (implementation complexity concern)

BM: The alternative is to not support AMD and provide only one imports

STH/RW: This is an option, but a worse option.

...Discussion re: static checking for non-ES6 modules

ARB: Every single construct, import, loading etc now has two different semantics to support.

BM: Forces users into thinking about which they need... optimizing for module authors, not module users. The wrong case... otherwise enforce static checking for all module code

AR/STH: Not possible for all existing code

STH: (whiteboard) Indirection via dynamic object makes static checking impossible.

For example, if you write the code:

1
2
import { a } from "some.js"
... a ...

where "some.js" is an AMD library, then there's no static checking, but if you refactor "some.js" to be an ES6 module, you automatically get static checking. But if you don't support this use case, then there's indirection:

1
2
import { exports } from "some.js"
... exports.a ...

And changing "some.js" to use ES6 never results in new static semantics.

...Mixed discussion re: dynamic checks vs static checks.

BM: Was under the impression that the dynamic checks might be too late, but it has now become clear that they happen early enough

STH: Cannot create references across Module instances to dynamic module code.

MM: the world of JS uses feature detection, on the AMD side... can AMD code feature test?

STH: (refers to an early slide, which shows example of importing module as single object, properties can then be tested for)

MM: (confirms that STH answers Q)

DH: Pause on the Question of dynamic import/export (Returns to the pipeline diagram) ...The "fetch" hook is the part where you go get the bits

DH: (Slide: 1. Load and Process Dependencies Diagram) (Slide: 2. Link)

AR/DH: Note that browsers can provide their own plugin points for the Fetch step

MM: All of the hooks have been executed and there is no user code? If this fails, there are no side effects?

DH: Correct

ARB/STH: During

DH: Modified the registry, but there is an inflight loading happening, when the inflight is finished, it will pave the changes to registry. (last op wins)

ARB: When you evaluate a script that imports module Foo, which runs hooks that in turn import Foo into the module registry, what happens?

AWB: Why are they operating in the same Realm?

DH: It sounds like an objection to modifying the list of modules in the registry by downloading code that modifies the list of modules in the registry...

STH: Imagine we didn't have loader hooks, all you could do was eval and had two XHRs that fetched and eval'ed. We'd still have the same issues that we'd have with loader hooks, it's a problem with mutation and concurrency.

ARB: Agree that the fundamental problem will always be there, but have a problem with shared global object for all modules.

DH: If the same module is attempted to be defined in two places, that's an error and is a bug.

ARB: Only when within the same compilation stage, silent overwriting otherwise.

WH: What if module A depends on both B and C and the initialization of B fails?

DH: C remains uninitialized but present in the registry

WH: This breaks the model. It's not C's fault that its initializer didn't run.

AWB: Mark C as never having its initializer attempt to run and run it the next time it's imported.

DH: Moving to next slide

(Slide: 3. Execute)

Produces "Result"

Note that each step in the 3 parts has an Error path:

  1. load/syntax error
  2. link error
  3. runtime exception

...Mixed discussion re: execution despite exceptions

...Mixed discussion clarifying fetch semantics (1. Load and Process) re: dynamically building URLs to batch load? re: browser knowledge of sources?

LH: What does the synchronous timeline of Slide 1 look like?

DH: All normalize hooks first (need names and locations), then all resolve hooks

link Use Case: Importing into Node

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
System.resolve = function(path, options) {
if (node.indexOf(path) > -1) {
return { name: path, metadata: { type: 'node' } };
} else {
return { name: path, metadata: { type: 'es6' } };
}
};
function extractNodeExports(loader, source) {
var loader = new Loader();
return loader.eval(`
var exports = {};
${source};
exports;
`);
}
System.link = function(source, options) {
if (options.metadata.type === 'node') {
return new Module(extractNodeExports(this, source));
}
}

link Use Case: Single Export Modules

DH: Brought this up 2 meetings ago, had a proposal that wasn't ready, it was shot down. This is something that I'm being told is very important and I agree with them. We can accommodate single exports via design protocols, but the developer community may not like it.

DH/YK: (walk through the System.link implementation)

DH: Can, should do better. Goal: Simple syntactic sugar. It's important, we will address it and we will do so with syntactic sugar. We will create a means by providing an "anonymous export". We will review the "sugar" at the next face-to-face meeting.

...Recognizes the community frustration regarding lack single/anonymous exports.

...No dissent.

LH: (Questions about how this works with the previously shown use cases)

...

YK: (Shares anecdotal experience from developing the ES6 transpiler that was adopted by Square. Positive experience.)

STH: Updated/removed junk from wiki

LH: Can imports be in scripts?

STH: Yes

DH: There was originally a use case that involved jQuery, we can't satisfy this without breaking everything (there is no way to be ES 3, 5, 6 at the same time)

But...

1
2
3
if (...some detection...) {
System.set("jquery", ...);
}
1
2
3
4
5
6
7
8
9
10
11
<!--
once this is loaded, the jQuery module is
registered and available for all scripts
-->
<script src="jquery.js"></script>
<!--
which means all future scripts may have this:
-->
<script>
import { $ } from "jquery";
</script>

LH: What about concatenation cases?

DH: (whiteboards example of System.ondemand)

1
2
3
System.ondemand({
"all.js": [ "a", "b", "c" ]
});

AWB/STH: (whiteboard)

m.js:

1
2
3
module "m" {
export let a = 1;
}

n.js:

1
2
3
module "n" {
export let b = 2;
}

Needs:

1
2
3
4
System.ondemand({
"m.js": "m",
"n.js": "n"
});

If you concatenate?

m.js + n.js = concat.js...

Needs:

1
2
3
System.ondemand({
"concat.js": [ "m", "n" ]
});

Arrays for files that contain multiple things

...

ARB: We're over-prioritizing for concatenation. The language shouldn't be hostile, but should stop at good enough. We shouldn't optimize the design of the language around a secondary concept

AWB: modules are a concrete concept in the language, we need to focus on these as a building block

LH:

STH: The claim that concatenation is going to become a not-important part of the web is ludicrous

ARB: I think that mid-term concatenation will harm performance

YK: Do you think that concatenation will go away?

ARB: In the long term, it might

YK/STH: This is what is ludicrous

...Mixed discussion re: library vs. language

AWB: There is a standard loader, defined by the language

...From Arv: AR: Joining files to optimize download and compilation

STH: YUI optimized for reality and found that concatting is important

YK: Should Ember ship 100 files?

AR: Any modern library has a lot of files. Apps/libraries are making trade-offs to get good performance.

DC: Caching is not working. Browser will get better.

AR: SPDY will make things better

YK: Even with SPDY, there is a lot of IO

ARB: It is perfectly fine to depend on a tool for concat

EA: We are designing based on concatenation. We should take that out of the picture. We can always write compilers that does the linking.

ARB/LH: With a compiler you can do linking/bundling and existing and future tools can do this.

STH/DH: There will be holes in these.

LH: module "a" { ... } is leading developers down the wrong path

STH: Recommmend doing modules the node style, where each file is a module

YK: AMD developers use a build system that adds the name to the define(). They don't name the modules in their source. The build system names the modules.

MM: AMD experience speaks in favor of a concatenator.

STH: You will get a compile time error if you import a file that contains a module. ...

ARB: How about adding a way to just register a module as a string containing the source of its body as if it was a file.

AR: Then you have to allocate the string ...

AWB: Wants to use module "abc" { ... }. It is a good way to structure code. And you don't want to tie this to your configuration management ...

STH: The strength of the system is that it supports both

ARB: The approach Allen wants is not well supported because it lacks lexical scoping

AR: If we use a string literal we cannot check the code to do prefetching etc

ARB: It is a string so the string only needs to be lexed, then the parsing etc can be paralellized, not so with embedded module declaration ...

ARB: There is no way to not modify the global registry when defining a module.

DH: The file system (in SML) is also a shared registry. The module registry is no different

ARB: Disagree. There is no way to create a local module here

STH: JS has a lot of ways to struccture code: functions, classes etc and modules do not need to fill this role

ARB: More interested in preventing accidents due to name clashes.

...Mixed discussion of module syntax related concerns

DH: Ability to prevent people from using module syntax?

MM: Yes

STH: For Andreas' concern, look for the names of module declaration strings, check the registry and if any already exist, error.

...Defining a loader with right hook, prevent the mutation of the registry by anyone that does not have access to the loader

MM: Satisfied from a security perspective.

ARB: Would prefer for the default behavior to error, need to be explicit if you want module to override in an imperative manner.

DH: Not opposed to moving towards scoped modules in the future. Just worried about complexities.

ARB: Only concerned about import scope semantics

STH: concern is that polyfills have to use eval and then System.set

ARB: good to make it clear that polyfills are doing some special

DH: agree with ARB about polyfills

STH: This is something to be deferred without blocking progress, but ok with changing to error to achieve consensus.

YK: agree with STH about consensus, but potentially concerned.

link Conclusion/Resolution

  • Default: declarative form of a module is an error if a module of the same name already exists in the module registry.
  • Using System.set to overwrite an existing module is not an error.
  • Behavior of errors during module initialization (when some module initializers don't even get started) is still unresolved.

jQuery Core Team Meeting – Mar 12 2013

March 11, 2013
Minutes (Notes) of the meeting of jQuery
Location: #jquery-meeting on Freenode
Attending: DaveMethvin, timmywil, mikesherov, rwaldron, orkel
Time: Noon ET

Official Agenda:

jQuery 2.0 Final

Ship for jQuery Uk (April 19)?

Stuff to be ironed out

.data() implementation

Use in node.js

other?

Sizzle ticket https://github.com/jquery/sizzle/pull/193

  • Timmy will land

jQuery 1.10

Hard to move quickly on this, we’ve given zero notice

Need to publicize changes (next bullet) and do a blog post

  • Dave to do blog post ASAP

Ship a month or two after 2.0? — mid-June would be Portland

(Add these to Migrate Plugin and document NOW for 2.0/1.10 release)

No script execute by default, must use $.parseHTML

  • Groundwork for XSS reduction, but not a complete fix atm
  • This would make the no-leading-space restriction unnecessary?

http://bugs.jquery.com/ticket/13417 domManip and empty text nodes

http://bugs.jquery.com/ticket/12838  $.ajax hook point for domManip

change Event.isTrigger from boolean to bitmask

allow multiple args for .replaceWith (ref)

jQuery 1.9.2 — Do we need one? (Doesn’t seem so, none scheduled)

Documentation Day

Tuesday March 12 8pm Eastern time #jquery-dev

Can we get the team together virtually to knock down the docs issues?

Document treatment of various node types ‘n stuff wrapped by jQuery

  • What can be put in a set?
  • What methods work with it?

bugs.jquery.com

  • New home page to improve people’s reporting — on Dave’s plate
  • e.g., docs issues go to api.jquery.com

Open tickets triage

jQuery Core Team Meeting – Mar 11 2013

  • Attending: DaveMethvin, timmywil, mikesherov, rwaldron, orkel

link jQuery 2.0 Final

link jQuery 1.10

  • Hard to move quickly on this, we’ve given zero notice
  • Need to publicize changes (next bullet) and do a blog post
    • Dave to do blog post ASAP
  • Ship a month or two after 2.0? — mid-June would be Portland

link (Add these to Migrate Plugin and document NOW for 2.0/1.10 release)

  • No script execute by default, must use $.parseHTML
    • Groundwork for XSS reduction, but not a complete fix atm
    • This would make the no-leading-space restriction unnecessary?
  • http://bugs.jquery.com/ticket/13417 domManip and empty text nodes
  • http://bugs.jquery.com/ticket/12838 $.ajax hook point for domManip
  • change Event.isTrigger from boolean to bitmask
  • allow multiple args for .replaceWith (ref)

link jQuery 1.9.2

  • Do we need one? (Doesn’t seem so, none scheduled)

link Documentation Day

  • Tuesday March 12 8pm Eastern time #jquery-dev
  • Can we get the team together virtually to knock down the docs issues?
  • Document treatment of various node types ‘n stuff wrapped by jQuery
    • What can be put in a set?
    • What methods work with it?

link bugs.jquery.com

  • New home page to improve people’s reporting — on Dave’s plate
  • e.g., docs issues go to api.jquery.com

link Open tickets triage

jQuery UI Team Meeting – Mar 06 2013

  • Investigating how much logic can move from grunt to download builder to reduce duplication.
  • Investigating the possibility of optional initialization for widgets.
    • Speeds up initial page load.
    • Ajax'd content "just works".
    • Requires the user to generate the full markup.
  • Working on a Pointer Events polyfill via jQuery special events.

jQuery Mobile Team Meeting – Feb 28 2013

  • Attending: Todd Parker, Jasper de Groot, Jason D Scott, Anne-Gaelle Colom, Gabriel Schulhof, Alex Schmitz

link Todd

  • jQuery 1.3.0 final released last Wednesday - http://jquerymobile.com/blog/2013/02/20/jquery-mobile-1-3-0-released/
    • Thanks for everyone who helped us get this release out, it’s feature-packed
  • No meeting last week due to the Vienna conference. Presented on RWD and jQM.
  • Website and blog need to get ported into the new template. Ralph and Anne to help with that process
  • 1.4.0 planning underway, UI, core and mobile folks discussing plans
  • Will be on vacation next week

link Jasper de Groot

  • worked on demo center, TR 1.3, triage

link Anne-Gaelle Colom

  • Tagged and released the API docs for 1.3.0 (under build 1.3.0-2)
  • Talked at the jQuery Europe conf (Good UI Design Principles with jQuery Mobile)
  • A bit of triage/testing

link Gabriel Schulhof

link Ghislain Seguin

  • Tracked down pending PR authors up to 6-month old to get them to sign a CLA
  • Updated Readme.md on master need to port to 1.3-stable
  • Listening in to the CLA automated validation conversation. Hopefully it comes sooner than later because the manual process is a real PITA
  • Little progress on unit/integration tests separation

link Alexander Schmitz

Testing Team Meeting – Feb 28 2013

February 28, 2013
Location: #jquery-meeting on Freenode
Attending: Timo, Dave, Scott, Jörn
Time: 11am ET (16:00 UTC)

QUnit

Starting splitting out add-ons
into separate repositories:

TestSwarm

Timo working on projects
refactoring: https://github.com/jquery/testswarm/tree/projects-4

Working with BrowserStack to fix
lost workers.

 

 

jQuery Core Team Meeting – Feb 25 2013

Attending: DaveMethvin, mikesherov, gibson042, rwaldron, timmywil

link jQuery 2.0b2

link jQuery 1.9.2

  • Still can wait a couple of weeks

link Documentation needs work

  • Dave to work on some of this in Toronto Monday
  • Move upgrade-guide stuff into api.jquery.com
  • Document treatment of various node types 'n stuff wrapped by jQuery
    • What can be put in a set?
    • What methods work with it?

link jQuery 1.10 correspondence with 2.0

link jQuery 1.10 and 2.0 final ship date

  • 2.0 to stay in beta until 1.10?
  • Encourage people to use the beta

link bugs.jquery.com

  • New home page to improve people's reporting -- on Dave's plate
    • e.g., docs issues go to api.jquery.com

link Open tickets triage