Nov 17 meeting notes

# Waldemar Horwat (13 years ago)

Here are my meeting notes for today.

Waldemar

WebIDL: Can abstract interfaces have static members? Don't see why not -- they'd just be spec sugar for adding the same static member to concrete classes that derive from those abstract interfaces. As usual, it would be a spec error to have a collision.

Debate over combination of overloaded methods from different base abstract interfaces. Issues come up with combining overloads of abstract types -- per yesterday, the structural "union" of two abstract interfaces A1 and A2 can contain instances that are in neither A1 nor A2. General feeling is to avoid the issues if feasible.

Property enumeration order: Decided that this is a TC39/ECMAScript issue, not a WebIDL issue.

Dealing with argument count mismatches: Ignoring additional arguments is useful for upwards compatibility (example: adding an extra dirty region argument to draw methods that would be ignored by older browsers that would just redraw the whole canvas).

Overloading is a mismatch with future-proofing argument count mismatches. Proposal: treat each function call as having infinitely many trailing "undefined" arguments, and overload only on types, not argument count.

Brendan on special operations: "don't want to see any more of these darken our door". Trouble is that these kinds of catch-alls allow most names but not all names, leading to brittle or exploitable code. It's better to provide get and set methods.

However, Stringifiers are ok.

Error objects have their string properties (name and message) defined on their prototypes in ES3. IDL errors can create instances with instance properties for name and message rather than delegating to a prototype, and everything ought to work.

Browsers like to add other properties to Error objects they create. Not clear how to link into that functionality. Throw this back to TC39's core language discussions.

Returned sequence types are returned as arrays. That means that they must be copies each time they're returned. Should they be frozen? Not much enthusiasm for that....

What about passing arrays into IDL? The IDL can just access whatever it wants because it has control until it returns. Except that it doesn't if there are getters, setters, or proxies in the data structure passed to IDL -- the order of accesses is discoverable, and the data structure can mutate itself as it's being read.

The proposal of having IDL read data structure "as if copied" is not practical. Some methods might only want to access one element of an array and don't want to copy the whole thing.

We won't require users to freeze arrays before passing them into IDL. That would be too cumbersome.

We won't require IDL to freeze arrays before passing them to users. Every array will be fresh.

Discussion about indexGetter and indexSetter. Separate path for looking up numerical indices?

John, Brendan: Want to avoid high management overhead for cooperating with W3C. A lot of liaisoning formality or large meeting would be undesirable.

Discussion about desirability of writing a style guide or joining TAG. Style guide may be ineffectual -- it's better to just have somone who understands style review proposals -- while TAG has no teeth to enforce its mission, so it's practically been ignored.


Next meeting on Jan 18-20 at Yahoo. Ballot resolution meeting at 3pm on Jan 19.

We'll send the final ISO draft to ISO tomorrow (Thursday) and also place the draft on the ECMA website. Allen: Need to re-designate the document as a draft if we let it out now.

Consensus on removing the test results altogether from the test262.ecmascript.org web site. Having results there would provide too many incentives for trying to game the system rather than build a good test suite.

Debate on whether do commit-before-review or review-before-commit on the test suite.

Would be good to get rid of the powershell platform dependency when submitting tests.

Discussion about whether we can get rid of -0. Some are in favor but no, we can't. We also can't make -0 !== +0. Either would be a large breaking change.

Some desire to make the identity operation syntactically as attractive as ===. Could we make the identity operation into an infix operator named "eq"?

Waldemar: Syntactically, we could, and we wouldn't even need to make "eq" into a reserved word. The production would have to be: expr1 [no line break here] eq expr2 The reason the [no line break here] has to be in the first gap instead of the second one is to maintain compatibility with the existing code that counts on semicolon insertion: a = x eq = y which would continue to parse as: a = x; eq = y; Agreed to move this into the proposal stage.

const function joining: Vigorous debate. Some don't like specifying the optimization algorithm. What is its asymptotic complexity? Oliver would object if it's greater than n*log(n) but might object anyway.

Waldemar: Opposed to mandating making dead code change semantics of live code, as in:

const debug = false; const divisible(m) { return const(list) { return list.filter(const(n) { if (debug) log(list); // dead code return n%m === 0; }); }; } Now the innermost function has different === function instance behavior thanks to the dead code it contains. The behavior ought to be identical to: const divisible(m) { return const(list) { return list.filter(const(n) { return n%m === 0; }); }; }

Debate over syntax. No particular resolution. Everyone seems to have a different view on this. A: Skeptical about syntax. B: Like it but would want to make joining implementation-defined. C: Don't think users will want to freeze functions much. D: Not convinced secure mashups have been demonstrated. E: Would like even shorter syntax. F: Figure out asymptotic complexity. G: Use λ as the syntax.

# Waldemar Horwat (12 years ago)

Here are my rough notes from today's meeting.

Waldemar

IPR discussions

Test262 status

Internationalization: due by March meeting if we want to try for June GA

Doug Crockfords's presentation at Silicon Valley Code Camp. User feedback gathered by Doug:

  • Users like quasis.

  • Half of the users vehemently opposed large syntax changes (paren-free etc.) that change syntax merely to add a different way of doing largely the same thing. They know that they don't have to use the new syntax, but they also don't want to see it in code they read.

  • Virtually all users hated block lambda.

  • Users not looking forward to new class syntax but not as opposed.

  • Users liked the ... operator.

  • Users would like some functionality to gather stack traces to do things like remote application diagnosis.

  • Users generally liked modules.

  • Confusion about map. Particularly for people who work on (geographic) maps.

  • Requests for Object.flatten (collapse prototype chain into one object), copy, and deep copy.

  • Users support elective use of Unicode characters as alternate forms of syntax tokens. Examples: ≤, λ, etc.

  • Some users wanted a NoSuchMethod trap on Object.prototype.

Allen's update on ES 6 Draft Specification

Allen: Wanted to allow an identifier named "arguments" only in the case where it's the ... parameter: function f(x, y, ... arguments) {...} Objections: Unnecessarily complex. This isn't the same as the deprecated meaning of arguments because it doesn't include x and y (and also is an array instead of an arguments object). Consensus: Don't make a special exception for use of the identifier "arguments" here.

function f(a, b = g()) { function g() {return a} } What happens here? Waldemar, DaveH, and several others: b's initializer doesn't see the internal definition of g because the call to g is outside the braced scope. A forward reference here is counterintuitive.

Oliver: What about these?

var x = 1; function f(a = x) { var x = 5; }

function g() {return "g1"} function f(a = g) { return a(); function g() {return "g2"} }

MarkM: Two-scope model (one scope for parameters, an independent inner scope for let, const, and var bindings). This model is upwards-compatible with ES5.1 strict because the latter disallows shadowing of a parameter by a binding in function scope.

Allen: Two-scope model, but with inner scope prohibited from shadowing parameters. MarkM: Likes this. Any program that is accepted works with either of the two-scope model intuitions.

Waldemar: What about this?

var d = 12; function f(a, b = a, c = d, d = 0) {...}

Do we have let, let*, or letrec semantics for a, b, c, and d?

Consensus: letrec with temporal dead zone, so the above would be an error when evaluating c's initializer because d hasn't been bound yet.

DaveH: Concerned about let temporal dead zone semantics (in general for let).

Waldemar: Dead zone very unlikely to come up for parameters in practice. The compiler can readily see if parameters are forward-referenced in uses. Of course, it is possible to come up with obscure cases that demonstrate the dead zone:

function f(a, b = function(){return d}, c = b(), d = 42) {...}

Waldemar: Point of order. Concerned about a number of items not approved in May appearing on the ES Harmony agenda for this meeting (section 5 of the meeting agenda). While Waldemar likes some of them and is as eager as anyone to discuss them, it would be better to separate them into a separate heading such as section 6 to make it clear to us and anyone watching whether the proposals are for ES.Next or for a future revision of ECMAScript. When posting agenda items, please indicate whether they're for ES.Next or for future revisions.

Internationalization presentation.

Allen: Can a web developer reasonably depend on his webapp working the same in a given locale on any conforming browser? Answer: No. MarkM: Are there specific areas where it's possible to pin implementations down more?

Alex: Wants a way to globally set a default localeList based on application-specific data. Long debate. Not possible as defined currently. Have the Globalization object default to getting a localeList from one of its user-settable properties if not provided in a function call? MarkM: Doesn't want mutable globals (other than ones that are set up once and then frozen). Alex: If you don't allow mutating the default, applications will still store the locale in a global and just pass the value of the global to every method that takes a locale, resulting in a more wordy program. Waldemar: Sometimes users will want to change their locale from within the application. Waldemar: While having either a mutable default locale or having no default locale would be ok, having a default immutable and implementation-dependent locale would be a problem, as it would be hard to usefully rely on such a thing.

Brendan: Looks like the identifier "Globalization" is used in existing JS libraries. Not sure in what capacity yet.

Timezone faithfulness across changes in the timezone laws issue.

Contains: Should the position parameter match IndexOf or lastIndexOf?

Array and string methods will continue to treat strings as pure sequences of 16-bit values.

randomInt is based on Math.random.

Will add erf/erfc/gamma if they're in the common math libraries.

Map/Set: Size property should be a getter property with no matching setter. It's defined on the property. What is its name? size, count, or length? Decide on es-discuss.

Default for-of iteration on Sets is clear. On Maps, should the default iteration return the keys or key-value pairs? for-in iteration on Maps and Sets doesn't do anything useful. You can ask for the other kinds of iteration on a Map by running a method (not a getter because it's not idempotent).

What is the order of enumeration? Insertion order (and without any exceptions for integral keys -- MarkM: who would define a language feature like that ;-)?

Does creating an iterator snapshot the object? Brendan: If enueration order is insertion order, a Map or Set would make a useful worklist abstraction as long as new elements do appear in iteration. Waldemar: What are the alternatives? Snapshotting would be heavy-weight. DaveH: The alternative is to throw from the iterator if the object has been modified since the previous iterator call. MarkM: Now in the worklist semantics camp, merely to avoid weird iterator state.

Argument over whether Map.prototype is a Map. We want to avoid the mess caused by Date.prototype being a Date (MarkM: It provides a hidden communication channel that cannot be frozen). What happens when you extract Map.prototype methods and apply them to an object that is not a Map? Type error. Allen: Wants the prototype to be an instance of the class for consistency. Waldemar, MarkM, DaveH: The prototype is not an instance of the class. Empirically, the only things that act as instances of user-defined classes are the things that inherit from the prototype, not the prototype itself. Will continue on es-discuss. However, we agree that there should be no mutable private state in the Map/Set constructors.

Also need to fix Date.prototype. Its private state should be frozen as well.

DaveH: Use === or egal? Distinguishing ±0 as separate slots in a Map or Set will confuse users. MarkM: What about defineOwnProperty? Same problem would appear there.

# Mikeal Rogers (12 years ago)

On Nov 16, 2011, at November 16, 20115:19 PM, Waldemar Horwat wrote:

  • Confusion about map. Particularly for people who work on (geographic) maps.

This is surprising. I might expect confusion with [].map() but not with geographic maps.

Is there any additional information about the pool that was surveyed?

# Brendan Eich (12 years ago)

On Nov 16, 2011, at 5:19 PM, Waldemar Horwat wrote:

Internationalization presentation.

Allen: Can a web developer reasonably depend on his webapp working the same in a given locale on any conforming browser? Answer: No. MarkM: Are there specific areas where it's possible to pin implementations down more?

Alex: Wants a way to globally set a default localeList based on application-specific data. Long debate. Not possible as defined currently. Have the Globalization object default to getting a localeList from one of its user-settable properties if not provided in a function call? MarkM: Doesn't want mutable globals (other than ones that are set up once and then frozen). Alex: If you don't allow mutating the default, applications will still store the locale in a global and just pass the value of the global to every method that takes a locale, resulting in a more wordy program. Waldemar: Sometimes users will want to change their locale from within the application. Waldemar: While having either a mutable default locale or having no default locale would be ok, having a default immutable and implementation-dependent locale would be a problem, as it would be hard to usefully rely on such a thing.

Brendan: Looks like the identifier "Globalization" is used in existing JS libraries. Not sure in what capacity yet.

I was looking a jquery-ui, whre Globalization appears to be a local var name. But there are other hits via codesearch.google.com to consider.

I also objected to gunning for early standardization with under-specification. ECMA-262 tends to specify for interoperation because web content can't choose the browsers it runs in, and fallback is not always graceful or even possible.

Maybe we can get two distinct (not both based on ICU) implementations done enough to interop-test by next March. I'm skeptical, and we should commit to doing the testing and removing under-specification that will bite developers and browser implementors, even if that takes us past next Spring's GA.

The issue of the G11N API being too Java-esque came up. We agreed to address it on es-discuss, with TC39ers beyond Allen participating.

Argument over whether Map.prototype is a Map. We want to avoid the mess caused by Date.prototype being a Date (MarkM: It provides a hidden communication channel that cannot be frozen).

The ES.next plan is to expose Date's internal [[PrimitiveValue]] property by a private-name-object key, so it can be prototype-delegated. This enables Mark's SES to freeze the @primitiveVaueKey directly via Object.defineProperty, even though Object.freeze skips private properties (per last TC39 meeting).

This approach can be used for other built-in constructor prototypes with mutable internal properties.

DaveH: Use === or egal? Distinguishing ±0 as separate slots in a Map or Set will confuse users. MarkM: What about defineOwnProperty? Same problem would appear there.

I suggested making a parameter (with a sane default value) to the Map and Set constructors by which the user could customize the e.r. used to partition mapped keys or values into equivalence classes.

# Gavin Barraclough (12 years ago)

On Nov 16, 2011, at 5:19 PM, Waldemar Horwat wrote:

Map/Set: Size property should be a getter property with no matching setter. It's defined on the property. What is its name? size, count, or length? Decide on es-discuss.

Hi Waldemar,

I'm unclear what "It's defined on the property" means, should this read "It's defined on the prototype"?

thanks, G.

# Mark S. Miller (12 years ago)

On Thu, Nov 17, 2011 at 12:12 AM, Gavin Barraclough <barraclough at apple.com>wrote:

On Nov 16, 2011, at 5:19 PM, Waldemar Horwat wrote:

Map/Set: Size property should be a getter property with no matching setter. It's defined on the property. What is its name? size, count, or length? Decide on es-discuss.

Hi Waldemar,

I'm unclear what "It's defined on the property" means, should this read "It's defined on the prototype"?

Yes, "prototype" was meant. Good catch.

# Axel Rauschmayer (12 years ago)

Map/Set: Size property should be a getter property with no matching setter. It's defined on the property. What is its name? size, count, or length? Decide on es-discuss.

Given that Array already uses length, it seems like the obvious choice.

Some of the things discussed should probably considered in the wider context of a well-designed collection library. Is anyone working on such a thing? Should there be efforts to make it happen (whether inside TC39 or externally, whether via a single party or via multiple parties)? It might not make it into ES.next, but it could inform decisions. Such a library is such a core element of a programming language that we should have a good one as soon as possible. The same holds for other utility functionality (IMHO, ES.next is still too frugal in this department).

Axel

# David Bruant (12 years ago)

Thanks for these notes.

Le 17/11/2011 02:19, Waldemar Horwat a écrit :

Here are my rough notes from today's meeting.

Waldemar

IPR discussions

Test262 status

Do you have any details on this point? A roadmap?

Thanks,

# David Bruant (12 years ago)

Le 17/11/2011 12:49, Axel Rauschmayer a écrit :

Map/Set:
Size property should be a getter property with no matching
setter.  It's defined on the property.
What is its name?  size, count, or length?  Decide on es-discuss.

Given that Array already uses length, it seems like the obvious choice.

Or is it? Array 'length' has some semantics. When you reduce it, elements get removed. This won't be true for maps and sets. Also, maybe it's because i'm a non-native English speaker, but for me 'length' refers to a measurement with something like a ruler. You start at 0 and see up to where it goes. This is very accurate for an array which is an indexed set (starting at 0 and growing) and for arrays as considered in C (continuous sequence of bytes) which ECMAScript arrays seem inspired of. This is probably less relevant for unordered collections such as sets which I'd tend to consider as a messy bag. For sets, 'count' sounds more relevant to me. I think I would go for 'count' as well for maps.

Some of the things discussed should probably considered in the wider context of a well-designed collection library. Is anyone working on such a thing? Should there be efforts to make it happen (whether inside TC39 or externally, whether via a single party or via multiple parties)? It might not make it into ES.next, but it could inform decisions. Such a library is such a core element of a programming language that we should have a good one as soon as possible. The same holds for other utility functionality (IMHO, ES.next is still too frugal in this department).

What more than existing arrays, and upcoming map and set would you suggest?

# David Bruant (12 years ago)

Le 17/11/2011 02:40, Mikeal Rogers a écrit :

On Nov 16, 2011, at November 16, 20115:19 PM, Waldemar Horwat wrote:

  • Confusion about map. Particularly for people who work on (geographic) maps. This is surprising. I might expect confusion with [].map() but not with geographic maps.

I'm realising just now that in a project with a friend we've been declaring a Map constructor [1]. Obviously, it is used with "new Map()" [2]

"Map" is very likely to be used in browser-based games and should probably be avoided as a core language identifier. Obviously, if maps and sets are part of a built-in module, there is no problem since the user will have the freedom to choose the naming she wants for the module elements.

David

[1] DavidBruant/Ludesik/blob/master/js/Map.js [2] DavidBruant/Ludesik/blob/master/js/Ludesik.js#L7

# Waldemar Horwat (12 years ago)

On Thu, Nov 17, 2011 at 3:49 AM, Axel Rauschmayer <axel at rauschma.de> wrote:

Given that Array already uses length, it seems like the obvious choice.

"length" is my choice as well, for the same reason. It's not writable in Maps and Sets, so the concerns about the semantics of writing it don't apply.

Waldemar
# Waldemar Horwat (12 years ago)

On Thu, Nov 17, 2011 at 12:12 AM, Gavin Barraclough <barraclough at apple.com> wrote:

On Nov 16, 2011, at 5:19 PM, Waldemar Horwat wrote:

Map/Set: Size property should be a getter property with no matching setter.  It's defined on the property. What is its name?  size, count, or length?  Decide on es-discuss.

Hi Waldemar, I'm unclear what "It's defined on the property" means, should this read "It's defined on the prototype"? thanks, G.

Yes, that's a typo that should be "prototype".

Waldemar
# Dean Landolt (12 years ago)

On Thu, Nov 17, 2011 at 1:16 PM, Waldemar Horwat <waldemar at google.com>wrote:

On Thu, Nov 17, 2011 at 3:49 AM, Axel Rauschmayer <axel at rauschma.de> wrote:

Given that Array already uses length, it seems like the obvious choice.

"length" is my choice as well, for the same reason. It's not writable in Maps and Sets, so the concerns about the semantics of writing it don't apply.

Who can resist such a juicy bikeshed...

Just wanted to jump in and say non-writable length is consistent with String behavior as well, but David makes a good point about length implying metric topology. David's suggestion of count is nice. ISTM what we're talking about is cardinality, but no need to get too silly w/ precision. Though size is just fine with me, and has plenty of prior art.

Whatever name is chosen I'd prefer it be something other than length, and for it to also exist on Array.prototype as a read-only property returning this.length. This way this new property becomes the new length for every "compound" type, whether it be an object, array, string, map, set, etc. And length would remain for all sequence (numerically-indexed) types.

# Nebojša Ćirić (12 years ago)

Internationalization presentation.

Allen: Can a web developer reasonably depend on his webapp working the same in a given locale on any conforming browser? Answer: No. MarkM: Are there specific areas where it's possible to pin implementations down more?

Alex: Wants a way to globally set a default localeList based on application-specific data. Long debate. Not possible as defined currently. Have the Globalization object default to getting a localeList from one of its user-settable properties if not provided in a function call? MarkM: Doesn't want mutable globals (other than ones that are set up once and then frozen). Alex: If you don't allow mutating the default, applications will still store the locale in a global and just pass the value of the global to every method that takes a locale, resulting in a more wordy program. Waldemar: Sometimes users will want to change their locale from within the application. Waldemar: While having either a mutable default locale or having no default locale would be ok, having a default immutable and implementation-dependent locale would be a problem, as it would be hard to usefully rely on such a thing.

Brendan: Looks like the identifier "Globalization" is used in existing JS libraries. Not sure in what capacity yet.

I was looking a jquery-ui, whre Globalization appears to be a local var name. But there are other hits via codesearch.google.com to consider.

I also objected to gunning for early standardization with under-specification. ECMA-262 tends to specify for interoperation because web content can't choose the browsers it runs in, and fallback is not always graceful or even possible.

Maybe we can get two distinct (not both based on ICU) implementations done enough to interop-test by next March. I'm skeptical, and we should commit to doing the testing and removing under-specification that will bite developers and browser implementors, even if that takes us past next Spring's GA.

The issue of the G11N API being too Java-esque came up. We agreed to address it on es-discuss, with TC39ers beyond Allen participating.

I've started two threads on es-discuss, one about the namespace the other about the API concerns. Thanks for the input.

# Brendan Eich (12 years ago)

On Nov 17, 2011, at 10:16 AM, Waldemar Horwat wrote:

On Thu, Nov 17, 2011 at 3:49 AM, Axel Rauschmayer <axel at rauschma.de> wrote:

Given that Array already uses length, it seems like the obvious choice.

"length" is my choice as well, for the same reason. It's not writable in Maps and Sets, so the concerns about the semantics of writing it don't apply.

The objection raised at the meeting is that, unlike arrays, there are no properties named 0, 1, ... [length - 1] on a map or a set.

# Brendan Eich (12 years ago)

On Nov 17, 2011, at 11:26 AM, Dean Landolt wrote:

Who can resist such a juicy bikeshed...

Yup.

Just wanted to jump in and say non-writable length is consistent with String behavior as well, but David makes a good point about length implying metric topology. David's suggestion of count is nice. ISTM what we're talking about is cardinality, but no need to get too silly w/ precision. Though size is just fine with me, and has plenty of prior art.

No one wanted anything as long as card... There was a large cohort in favor of count, I thought. Some were ok with size.

Whatever name is chosen I'd prefer it be something other than length, and for it to also exist on Array.prototype as a read-only property returning this.length. This way this new property becomes the new length for every "compound" type, whether it be an object, array, string, map, set, etc. And length would remain for all sequence (numerically-indexed) types.

Agreed emphatically.

I like count best at the moment.

# Waldemar Horwat (12 years ago)

Array destructuring and length: let [a, b, c, d, ... r] = {2: 3} <| [1, 2] Obvious: a is 1; b is 2. What are c, d, and r? c = 2. d = undefined. r = empty.

Fixed property destructuring doesn't rely on length. Vararg r destructuring uses length. The semantics of length will match that of slice.

Allen: We may upgrade ToUint32 to ToInteger in various array semantics.

What should the semantics be if we allow fixed properties in the middle of a destructuring? [a, ... r, b] = [42] What are the values of a, r, and b? a = 42 r = [] b = undefined

Brendan: [a, ... r, b] = [, 43] <| [42] What are the values of a, r, and b? a = 42 r = [] b = 43 or undefined?

Array.from discussion: What happens if you subclass Array? Subarray = Array <| function() {...} Subarray.from(arraylike)

DaveH: Array.from = function(x) { var result = new this(); for (var i = 0, n = x.length; i < n; i++) result[x] = x[i]; return result; }

Array.of = function(... x) { var result = new this(); for (var i = 0, n = x.length; i < n; i++) result[x] = x[i]; return result; }

The above should skip holes.

MarkM: Now these functions are this-sensitive and will fail if extracted and called indirectly. DaveH: Replace 'new this()' with 'new (this || Array)()' above. MarkM: Of all of the static methods in ES5, not one of them is this-sensitive. The simple extraction of a static method fails, thereby making static methods not be first-class. If Math.sin did this, you couldn't map it over an array. With this, you can't map Array.of over an array. Doug: Concerned about the use of the word 'of'; confusion with for-of. Wild debate over class hierarchies and class-side inheritance. Deferred Array.from and Array.of due to concerns over this-sensitivity until we figure out a proper class-side abstraction mechanism.

Array.from(a) is superfluous because it's expressed even simpler as [... a]. DaveH withdrew it.

Array.pushAll: Debate over whether this is a workaround for poor implementations of using Array.push with spread or apply, or whether we should directly have a second set of methods. Brendan: Let's implement spread and optimize it first. Later we can always add pushAll if it's needed. "This isn't ... paving cowpaths; this is a mountain goat that went too high".

DaveH: Very opposed to .{ .

Cut 'fine points of for-of' from this meeting due to time.

Batch assignment: Is this ES6 or ES7? This is new, not discussed in May. Can't discuss batch assignment without also discussing .{ . Was .{ part of the May object literal proposal? MarkM: Two kinds of .{ collisions to worry about. The object literal just statically disallows them. .{ can have run-time property collisions. DaveH: Like the functionality but not the .{ syntax.

Example from .= page:

let element = document.querySelector('...'); element.{ textContent: 'Hello world' }.{ style.{ color: 'red', backgroundColor: 'pink' } }.{ // back on element onclick: alert };

Waldemar: Can you replace }.{'s with commas? Brendan: Not in general. }.{'s do property redefinitions on property name conflicts, while commas produce errors on conflicts. Waldemar: Can you distribute the middle section above into the following? }.{ style.{color: 'red'}, style.{backgroundColor: 'pink'} }.{ // back on element Answer: Maybe.

DaveH: Bind operator syntax strawman. softBind strawman. [A bunch of different discussions going on simultaneously, which I couldn't track.]

Direct Proxies slide show.

Discussion about what hidden or implementation properties are passed from the target through a direct proxy and how a proxy handler would find out about all of them. The author of a proxy needs to keep up to date about picking the correct target as we add hidden properties. For example, to make an Array-like proxy object, a proxy should start with an Array instance as the proxy target. Same with Date, etc. Allen: There's no way to bootstrap -- can't define an Array-like proxy if you don't have an Array target to start with. Discussion about proxying the [[class]] name.

No more fundamental vs. derived traps. (Almost) all traps default to the target object's behavior if not overridden. An exception is the construct trap, which by default calls the call trap instead of forwarding to the target object. Allen: Should just pass through to the target. Allen worried about other derived traps. Waldemar: Always defaulting to the target will prevent us from ever defining new non-leaf traps in the future, as that would break existing proxies. For example, if we have a current trap API where the proxy defines only the trap GET, and we later wish to evolve the language to refactor the API to call the derived trap HAS followed by GET, where an object's HAS is defined in terms of GET, then defaulting to the target will break proxies because HAS will invoke the target's GET instead of the proxy's GET. MarkM: This is forwarding vs. delegation. The issue applies to many traps, not just call. All non-leaf traps should be resolved in the same way. Allen: Get rid of non-leaf traps (i.e. make them nonoverridable, allowing proxies to override only the leaf traps into which the non-leaf traps decompose). MarkM: Why? Waldemar: Are there any derived traps that have additional intelligence not expressible via the leaf traps which they call? Allen: Future-proofing is not important because we're unlikely to change the proxy API in the future. Waldemar: Counterexamples: Classes (if they're not just sugar), guards, value proxies, ... Sam, MarkM: The language provides a prototype handler with reasonable defaults for derived traps. Proxy handlers derive their handlers from that prototype. When the language evolves to create new traps, the language's prototype handler evolves in lockstep to keep existing proxies working. Discussion about double-lifting (making the proxy handler also be a proxy so it can abstract over the proxy trap API) and future-proofing membranes.

Make target always be the first handler parameter instead of always being the last? That would make it match the Reflect API. What does receiver do in Reflect.get/set/call(target, receiver, ...)? Make target first and receiver last in the handler API. The Reflect API can drop the extraneous receiver parameter. MarkM: That doesn't make sense for Reflect.call. The order should be Reflect.call(target, receiver, args), not Reflect.call(target, args, receiver). Note that args is an array, not a spread list of arguments. Discussion about what Reflect.call should be called. The name "invoke" was invoked. "apply" might also apply here.

Object.preventExtensions is a leaf trap and calls handler.protect('preventExtensions'). Object.seal and Object.freeze: Should these call handler.protect('seal') and handler.protect('freeze')? Replace them with separate handler traps? Replace them with calls to a large number of separate traps that individually seal or freeze properties?

MarkM: Why not define call behavior as target function behavior instead of having a call trap? Waldemar: That would break double lifting.

Nonconfigurability invariants:

Waldemar: get/set can still get and set own properties even on frozen objects with fully frozen prototype chains. Sam, MarkM: True. Unfortunately it's too hard to enforce this invariant.

Tom: Use a null target to indicate a permanently "virtual" object. Brendan: Proxy.DonJuan

Tom: Replace synchronization actions with throws if the synchronization actions would make any modifications to the target object.

Discussion of proto. Brendan: It's a real use case in object literals.

Proxy.stopTrapping: Can approximate this by deleting all handler bindings from the handler. MarkM: Swap arrow by making the proxy be the target and target be a proxy? Consensus: Dropped stopTrapping

Refactoring prototype climbing in the spec. Refactoring: Brendan: Don't get rid of Object.getPropertyDescriptor and Object.getPropertyNames even if they aren't traps.

Bikeshedding Proxy.for and Proxy.create names. Why isn't Proxy a module? if it's a module, can't use Proxy.for unqualified because it's a keyword.

Tom: Direct proxy refactoring takes care of the set/put/canPut chaining problem.

Should we have a defaultValue trap? Brendan: Leave it out for now. Revisit when we do value proxies.

Attach: If target is a proxy, call a new trap. Tie ability to attach to object extensibility. Waldemar: Won't work for host objects that need to be both secure and extensible. MarkM: This is especially evil in capturing function arguments. If Alice gives Bob and Cathy a plain ES5 function, Cathy can't peek at the arguments Bob passes to the function when he calls it. With Attach, Cathy can intercept Bob's calls to Alice's function and, worse, make the function do something different for Bob. Discussion about whether this should be done. A number of us want value observers and feel that proxies are less useful without them. DaveH: There are many things that are wanted that didn't make the ES.next cut.

Consensus: Direct proxies (other than startTrapping/attach) accepted for ES.next to replace older proxies proposals and strawmen.

2012 meetings: Jan 18-19 at Yahoo Mar 28-29 Google May 23-24 Northeastern University, Boston Jul 25-26 Microsoft Redmond Sep 24-25 Mozilla Nov 28-29 Apple

# Rick Waldron (12 years ago)

On Thu, Nov 17, 2011 at 7:40 PM, Waldemar Horwat <waldemar at google.com>wrote:

Array destructuring and length: let [a, b, c, d, ... r] = {2: 3} <| [1, 2] Obvious: a is 1; b is 2. What are c, d, and r? c = 2. d = undefined. r = empty.

Fixed property destructuring doesn't rely on length. Vararg r destructuring uses length. The semantics of length will match that of slice.

Allen: We may upgrade ToUint32 to ToInteger in various array semantics.

What should the semantics be if we allow fixed properties in the middle of a destructuring? [a, ... r, b] = [42] What are the values of a, r, and b? a = 42 r = [] b = undefined

Brendan: [a, ... r, b] = [, 43] <| [42] What are the values of a, r, and b? a = 42 r = [] b = 43 or undefined?

Array.from discussion: What happens if you subclass Array? Subarray = Array <| function() {...} Subarray.from(arraylike)

DaveH: Array.from = function(x) { var result = new this(); for (var i = 0, n = x.length; i < n; i++) result[x] = x[i]; return result; }

Array.of = function(... x) { var result = new this(); for (var i = 0, n = x.length; i < n; i++) result[x] = x[i]; return result; }

The above should skip holes.

MarkM: Now these functions are this-sensitive and will fail if extracted and called indirectly. DaveH: Replace 'new this()' with 'new (this || Array)()' above. MarkM: Of all of the static methods in ES5, not one of them is this-sensitive. The simple extraction of a static method fails, thereby making static methods not be first-class. If Math.sin did this, you couldn't map it over an array. With this, you can't map Array.of over an array. Doug: Concerned about the use of the word 'of'; confusion with for-of. Wild debate over class hierarchies and class-side inheritance. Deferred Array.from and Array.of due to concerns over this-sensitivity until we figure out a proper class-side abstraction mechanism.

Array.from(a) is superfluous because it's expressed even simpler as [... a]. DaveH withdrew it.

Perhaps Array.from() was either misunderstood or miscommunicated. I had prepared a complete step-by-step production of the function's semantics and documented them here:

gist.github.com/1074126

These steps support back compat to older JS (and DOM) implementations for converting any array looking object (arguments, DOM NodeLists, DOMTokenList (classList), typed arrays... etc.) into a new instance of a real array.

This is a real problem, in real JavaScript, in the real world. Considering the positive response from actual developers in the JS community, I'd like to ask that it be reconsidered.

# Brendan Eich (12 years ago)

On Nov 17, 2011, at 4:40 PM, Waldemar Horwat wrote:

Tom: Use a null target to indicate a permanently "virtual" object. Brendan: Proxy.DonJuan

He refuses to commit.

# David Herman (12 years ago)

On Nov 17, 2011, at 5:20 PM, Rick Waldron wrote:

On Thu, Nov 17, 2011 at 7:40 PM, Waldemar Horwat <waldemar at google.com> wrote: Array.from(a) is superfluous because it's expressed even simpler as [... a]. DaveH withdrew it.

Perhaps Array.from() was either misunderstood or miscommunicated. I had prepared a complete step-by-step production of the function's semantics and documented them here:

It turns out that [...arrayLikeThingy] does exactly the same thing; it constructs a new Array from the contents of any array-like object.

gist.github.com/1074126

These steps support back compat to older JS (and DOM) implementations for converting any array looking object (arguments, DOM NodeLists, DOMTokenList (classList), typed arrays... etc.) into a new instance of a real array.

This is a real problem, in real JavaScript, in the real world. Considering the positive response from actual developers in the JS community, I'd like to ask that it be reconsidered.

The reason why we decided to table the statics was that we had some serious questions about inheritance of statics and how they should behave, which is part of the ongoing discussions about classes. Given that spread (the ... syntax) gives you exactly the behavior you want, and it's actually very clear and even more concise than Array.from, it didn't seem worth taking more time discussing it now.

# Dominic Cooney (12 years ago)

On Fri, Nov 18, 2011 at 9:40 AM, Waldemar Horwat <waldemar at google.com>wrote:

Array destructuring and length: let [a, b, c, d, ... r] = {2: 3} <| [1, 2] Obvious: a is 1; b is 2. What are c, d, and r? c = 2.

Nit: This should be c = 3, because {2: 3} means ({2: x} <| [1, 2])[2] is x, right?

# Peter van der Zee (12 years ago)

On Thu, Nov 17, 2011 at 10:02 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 17, 2011, at 11:26 AM, Dean Landolt wrote:

Who can resist such a juicy bikeshed...

Please keep the general js api consistent. We don't use "count" for anything to consider "the number of elements in the structure" (actually, we don't use it at all), so why start now. It will create more confusion and frustration to devs than the possible confusion of the semantic interpretation of the word "length" in contrast with the name of the structure. At some point I'm starting to wonder who we're actually catering with these proposals...

# David Bruant (12 years ago)

Le 18/11/2011 01:40, Waldemar Horwat a écrit :

Array.from discussion: What happens if you subclass Array? Subarray = Array <| function() {...} Subarray.from(arraylike)

Subarray having a 'from' method sounds like a good idea, but it inheriting it from Array sounds counter-intuitive, because Array is indeed more of a placeholder than anything else. Very much like Object.getOwnPropertyDescriptor. I raised the concern earlier and I still think that we should separate the 2 different concerns <| is currently addressing.

  1. Object.getPrototypeOf(Subarray) === Array (hence the inheritance of 'from')
  2. Object.getPrototypeOf(Subarray.prototype) === Array.prototype (which is convenient for instanciation)

If we had an operator dedicated to 2, there wouldn't be any Subarray.from method. Just for this email, i'll use <|| for 1 and <<| for 2 (for explanatory purposes, not as syntax proposition)

MarkM: Now these functions are this-sensitive and will fail if extracted and called indirectly. DaveH: Replace 'new this()' with 'new (this || Array)()' above. MarkM: Of all of the static methods in ES5, not one of them is this-sensitive. The simple extraction of a static method fails, thereby making static methods not be first-class. If Math.sin did this, you couldn't map it over an array. With this, you can't map Array.of over an array.

What about Function.prototype.of? Or rather:

ArrayLikeCstrProto = Function.prototype <|| {of:function(){}}; // "of" is the this-sensitive one // In essence: Array.of = ArrayLikeCstrProto.of.bind(Array);

Subarray = ArrayLikeCstrProto <|| Array <<| function(){}

Subarray.of is inherited from ArrayLikeCstrProto. Instance prototype chain: (new Subarray) --> Subarray.prototype --> Array.prototype --> ...

Direct Proxies slide show.

(...)

Attach: (...) A number of us want value observers and feel that proxies are less useful without them.

What is wrong with a separate API like strawman:observe ?

Consensus: Direct proxies (other than startTrapping/attach) accepted for ES.next to replace older proxies proposals and strawmen.

Great!

# David Herman (12 years ago)

On Nov 17, 2011, at 5:20 PM, Rick Waldron wrote:

This is a real problem, in real JavaScript, in the real world. Considering the positive response from actual developers in the JS community, I'd like to ask that it be reconsidered.

You can write this function in JS today:

function array(x) {
    var result = [];
    for (var i = 0, n = x.length; i < n; i++) {
        if (i in x)
            result[i] = x[i];
    }
    return result;
}

But new Array class methods touch on open issues related to classes:

https://gist.github.com/1376730
# Brendan Eich (12 years ago)

On Nov 18, 2011, at 2:00 AM, Peter van der Zee wrote:

On Thu, Nov 17, 2011 at 10:02 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 17, 2011, at 11:26 AM, Dean Landolt wrote:

Who can resist such a juicy bikeshed...

Please keep the general js api consistent. We don't use "count" for anything to consider "the number of elements in the structure" (actually, we don't use it at all), so why start now. It will create more confusion and frustration to devs than the possible confusion of the semantic interpretation of the word "length" in contrast with the name of the structure.

Bad form, rehashing without responding to the substantive objection (raised in the immediately preceding message) to 'length':

The objection raised at the meeting is that, unlike arrays, there are no properties named 0, 1, ... [length - 1] on a map or a set.

Where pray tell is 'length' used for "the number of elements in the structure" but "the structure" has no indexed properties in the range [0, length)? Having length but no indexed properties at all will create confusion.

At some point I'm starting to wonder who we're actually catering with these proposals...

Save it. Your response is catering to inconsistent and incomplete argumentation. Respond to all the arguments on the other side before throwing stones.

# Rick Waldron (12 years ago)

On Thu, Nov 17, 2011 at 11:06 PM, David Herman <dherman at mozilla.com> wrote:

On Nov 17, 2011, at 5:20 PM, Rick Waldron wrote:

On Thu, Nov 17, 2011 at 7:40 PM, Waldemar Horwat <waldemar at google.com>wrote:

Array.from(a) is superfluous because it's expressed even simpler as [... a]. DaveH withdrew it.

Perhaps Array.from() was either misunderstood or miscommunicated. I had prepared a complete step-by-step production of the function's semantics and documented them here:

It turns out that [...arrayLikeThingy] does exactly the same thing; it constructs a new Array from the contents of any array-like object.

Based on: harmony:rest_parameters...On first look, I wouldn't guess that [ ...arrayLikeThingy ] behaved that way, but thanks for the clarification.

Rest params are undoubtedly one of the best new syntax features coming to ES.next, they compliment and enhance JavaScript's already very expressive nature. AFAICT, their only drawback is the wait we have until they are a reality.

To further drive the case for Array.from( arraylike ) I've posted a survey to Twitter, which I'd like to share the results of here:

docs.google.com/spreadsheet/ccc?key=0Ap5RnGLtwI1RdFNCbi13WlllOTk3bDJyb3laNFBneFE

Please read the comments as well.

# Brendan Eich (12 years ago)

On Nov 18, 2011, at 7:15 AM, David Bruant wrote:

Subarray having a 'from' method sounds like a good idea, but it inheriting it from Array sounds counter-intuitive, because Array is indeed more of a placeholder than anything else. Very much like Object.getOwnPropertyDescriptor.

It depends. I really put the "Java" in "JavaScript" by not making a Smalltalk-like metaclass hierarchy parallel to the instance hierarchy. However, people using JS (directly and via languages such as CoffeeScript) do simulate class-side inheritance, either by copying or via proto hacks.

Some (at least MarkM) on TC39 think class-side is malum in se and so should be _malum prohibitum. Others (Allen would be a good exponent, veteran Smalltalker that he is) are in favor.

Dave pointed out how harmony:binary_data (see lib/exe/detail.php?id=harmony%3Abinary_data_semantics&cache=cache&media=harmony:meta-class_diagram.png in particular) uses parallel constructor-side (and constructor-generator side) delegation to good effect.

So we have an open issue. Principled discussion of whether and how to heal the rift between the built-ins and user-defined constructors, what <| should do with function operands, etc. is welcome.

If we had an operator dedicated to 2, there wouldn't be any Subarray.from method. Just for this email, i'll use <|| for 1 and <<| for 2 (for explanatory purposes, not as syntax proposition)

"Do both" is frowned upon if we can find consensus in favor of one way. Allen's point IIUC in making superFunc <| function (...) {...} wire up the function expression's .prototype to delegate to superFunc.prototype is that not doing that, while making the resulting function delegate to superFunc, does something even less common (unheard of), choice 3 in this list:

  1. No class-side inheritance.
  2. Class-side inheritance, meaning that if D <| C for constructors D and C, then D.prototype <| C.prototype (using <| freely here for [[Prototype]] linkage).
  3. Constructor-side but not parallel prototype-side delegation.

Is there any known code (JS library, one-off app, even a non-counterexample gist) that chooses 3?

Direct Proxies slide show.

(...)

Attach: (...) A number of us want value observers and feel that proxies are less useful without them. What is wrong with a separate API like strawman:observe ?

Nothing except (a) misnamed wiki page :-P; (b) late (day-before) arrival for ES.next; (c) separate and different. (c) is the big one. If we can subset direct proxies that can attach or startTrapping, that seems better than disjoint intercession APIs, one stratified, the other unstratified and unrelated in signature, trap semantics, etc.

Consensus: Direct proxies (other than startTrapping/attach) accepted for ES.next to replace older proxies proposals and strawmen. Great!

Yes indeed.

# Brendan Eich (12 years ago)

On Nov 18, 2011, at 8:54 AM, Rick Waldron wrote:

On Thu, Nov 17, 2011 at 11:06 PM, David Herman <dherman at mozilla.com> wrote: On Nov 17, 2011, at 5:20 PM, Rick Waldron wrote:

On Thu, Nov 17, 2011 at 7:40 PM, Waldemar Horwat <waldemar at google.com> wrote: Array.from(a) is superfluous because it's expressed even simpler as [... a]. DaveH withdrew it.

Perhaps Array.from() was either misunderstood or miscommunicated. I had prepared a complete step-by-step production of the function's semantics and documented them here:

It turns out that [...arrayLikeThingy] does exactly the same thing; it constructs a new Array from the contents of any array-like object.

Based on: harmony:rest_parameters ...On first look, I wouldn't guess that [ ...arrayLikeThingy ] behaved that way, but thanks for the clarification.

Quick reply to suggest that rest is the wrong proposal. You want

harmony:spread, harmony:spread#11.1.4_array_initialiser

# Rick Waldron (12 years ago)

snip Quick reply to suggest that rest is the wrong proposal. You want

harmony:spread

harmony:spread#11.1.4_array_initialiser

Thanks! That's a much better resource - and the [...arrayish] example does make sense now

# Waldemar Horwat (12 years ago)

On 11/17/2011 10:03 PM, Dominic Cooney wrote:

On Fri, Nov 18, 2011 at 9:40 AM, Waldemar Horwat <waldemar at google.com <mailto:waldemar at google.com>> wrote:

Array destructuring and length:
let [a, b, c, d, ... r] = {2: 3} <| [1, 2]
Obvious: a is 1; b is 2.
What are c, d, and r?
c = 2.

Nit: This should be c = 3, because {2: 3} means ({2: x} <| [1, 2])[2] is x, right?

Correct. Sorry for the typo.

 Waldemar
# David Herman (12 years ago)

On Nov 17, 2011, at 10:16 AM, Waldemar Horwat wrote:

On Thu, Nov 17, 2011 at 3:49 AM, Axel Rauschmayer <axel at rauschma.de> wrote:

Given that Array already uses length, it seems like the obvious choice.

"length" is my choice as well, for the same reason. It's not writable in Maps and Sets, so the concerns about the semantics of writing it don't apply.

Calling it "length" would be a mistake. The word "length" means the measurement of a sequence:

http://dictionary.reference.com/browse/length

Maps and sets are not intended to be ordered data structures. Their intended use is for programs that do not depend on any order of the data.

# David Herman (12 years ago)

On Nov 18, 2011, at 2:00 AM, Peter van der Zee wrote:

On Thu, Nov 17, 2011 at 10:02 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 17, 2011, at 11:26 AM, Dean Landolt wrote:

Who can resist such a juicy bikeshed...

Please keep the general js api consistent.

A foolish consistency...

We also use 'hasOwnProperty' and 'forEach' and 'toLocaleString' in JS. Why not use those names? Because it's not the same operation. Neither is it the same thing as .length. An array is a sequential data structure, so it uses .length. A map and a set is not a sequential data structure, so it should not.

# David Herman (12 years ago)

On Nov 23, 2011, at 10:17 AM, David Herman wrote:

On Nov 18, 2011, at 2:00 AM, Peter van der Zee wrote:

On Thu, Nov 17, 2011 at 10:02 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 17, 2011, at 11:26 AM, Dean Landolt wrote:

Who can resist such a juicy bikeshed...

Please keep the general js api consistent.

A foolish consistency...

An additional point about consistency: many scripting languages talk about the "length" of a table data structure because they actually expose the representation of a table as an array or list. IIRC Perl/PHP associative arrays, Python dicts, Lisp alists, and Ruby hashes are all transparently built from arrays or lists. But Map and Set aren't arrays, they're their own data structure. So IMO it makes sense to name their methods on their on terms, not on the terms of a different data structure.

# Dean Landolt (12 years ago)

On Wed, Nov 23, 2011 at 1:17 PM, David Herman <dherman at mozilla.com> wrote:

On Nov 18, 2011, at 2:00 AM, Peter van der Zee wrote:

On Thu, Nov 17, 2011 at 10:02 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 17, 2011, at 11:26 AM, Dean Landolt wrote:

Who can resist such a juicy bikeshed...

Please keep the general js api consistent.

A foolish consistency...

We also use 'hasOwnProperty' and 'forEach' and 'toLocaleString' in JS. Why not use those names? Because it's not the same operation. Neither is it the same thing as .length. An array is a sequential data structure, so it uses .length. A map and a set is not a sequential data structure, so it should not.

As a thought experiment imagine someone were to propose Object.prototype.length -- what exactly would you expect that to mean? How would this be any different than Map.prototype.length? It'd be just as nonsensical. I could see keyLength being here, and something like itemLength being logical for sets, but these two concepts really are the same. It could also be said that a set's itemLength is the same concept as an array's.

This merits a new property, delegating the length property where it makes sense (sequences). IMHO the count property captures this intension nicely. Something like this, perhaps:

Object.prototype.count => total keys

Map.prototype.count => total keys

Set.prototype.count => total items

Array.prototype.length => length

Array.prototype.count => Array.prototype.length (sans holes?)

String.prototype.length => length

String.prototype.count => String.prototype.length

# Axel Rauschmayer (12 years ago)

Please keep the general js api consistent.

A foolish consistency...

We also use 'hasOwnProperty' and 'forEach' and 'toLocaleString' in JS. Why not use those names? Because it's not the same operation. Neither is it the same thing as .length. An array is a sequential data structure, so it uses .length. A map and a set is not a sequential data structure, so it should not.

I do get the point, though: Whatever is introduced should be supported consistently. But that is already in the works, if arrays will indeed have the same size/cardinality-related property as collections.

The negative example is Java, where you have length, length(), size() and many other things. JavaScript is still fairly uniform, with the DOM being the exception.

# Dean Landolt (12 years ago)

On Wed, Nov 23, 2011 at 1:29 PM, Dean Landolt <dean at deanlandolt.com> wrote:

On Wed, Nov 23, 2011 at 1:17 PM, David Herman <dherman at mozilla.com> wrote:

On Nov 18, 2011, at 2:00 AM, Peter van der Zee wrote:

On Thu, Nov 17, 2011 at 10:02 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 17, 2011, at 11:26 AM, Dean Landolt wrote:

Who can resist such a juicy bikeshed...

Please keep the general js api consistent.

A foolish consistency...

We also use 'hasOwnProperty' and 'forEach' and 'toLocaleString' in JS. Why not use those names? Because it's not the same operation. Neither is it the same thing as .length. An array is a sequential data structure, so it uses .length. A map and a set is not a sequential data structure, so it should not.

As a thought experiment imagine someone were to propose Object.prototype.length -- what exactly would you expect that to mean? How would this be any different than Map.prototype.length? It'd be just as nonsensical. I could see keyLength being here, and something like itemLength being logical for sets, but these two concepts really are the same. It could also be said that a set's itemLength is the same concept as an array's.

This merits a new property, delegating the length property where it makes sense (sequences). IMHO the count property captures this intension nicely. Something like this, perhaps:

Object.prototype.count => total keys Map.prototype.count => total keys Set.prototype.count => total items Array.prototype.length => length Array.prototype.count => Array.prototype.length (sans holes?) String.prototype.length => length String.prototype.count => String.prototype.length

Hmm...more consistent would be for Array.prototype.count to skip holes and add in the count of non-integer keys. This would be a very handy addition to the standard lib -- IIUC there's no efficient way to do this now.

Would it be asking too much for String.prototype.count to return total unicode characters? :P

# Michael Haufe (12 years ago)

On Wed, Nov 23, 2011 at 12:15 PM, David Herman <dherman at mozilla.com> wrote:

Calling it "length" would be a mistake. The word "length" means the

measurement of a sequence:

Of course, the word "magnitude" could consistently apply to arrays, sets, numbers, maps, and so on. No one would want to write it though...

# Brendan Eich (12 years ago)

On Nov 23, 2011, at 10:29 AM, Dean Landolt wrote:

Object.prototype.count => total keys

Once upon a time, SpiderMonkey supported count (acted like a readonly accessor on Object.prototype but masqueraded as own in objects delegating to O.p), whose value was the number of enumerable properties.

# Dean Landolt (12 years ago)

On Wed, Nov 23, 2011 at 2:11 PM, Michael Haufe <tno at thenewobjective.com>wrote:

On Wed, Nov 23, 2011 at 12:15 PM, David Herman <dherman at mozilla.com>wrote:

Calling it "length" would be a mistake. The word "length" means the measurement of a sequence:

Of course, the word "magnitude" could consistently apply to arrays, sets, numbers, maps, and so on. No one would want to write it though...

Actually no: we already have magnitude in the form of valueOf. This would be more akin to cardinality, but again, who wants to type that :)

# Dmitry Soshnikov (12 years ago)

On 23.11.2011 23:14, Brendan Eich wrote:

On Nov 23, 2011, at 10:29 AM, Dean Landolt wrote:

Object.prototype.count => total keys Once upon a time, SpiderMonkey supported count (acted like a readonly accessor on Object.prototype but masqueraded as own in objects delegating to O.p), whose value was the number of enumerable properties.

Just a small note: besides, count can be supported w/o for-in enumeration each time per reading this accessor -- via proxies (from my old experiments: Python's "magic names" inc. count

# Dean Landolt (12 years ago)

On Wed, Nov 23, 2011 at 2:15 PM, Dean Landolt <dean at deanlandolt.com> wrote:

On Wed, Nov 23, 2011 at 2:11 PM, Michael Haufe <tno at thenewobjective.com>wrote:

On Wed, Nov 23, 2011 at 12:15 PM, David Herman <dherman at mozilla.com>wrote:

Calling it "length" would be a mistake. The word "length" means the measurement of a sequence:

Of course, the word "magnitude" could consistently apply to arrays, sets, numbers, maps, and so on. No one would want to write it though...

Actually no: we already have magnitude in the form of valueOf. This would be more akin to cardinality, but again, who wants to type that :)

Meh, I should have hit wikipedia first. Looks like magnitude and cardinality are both pretty much absolute value. But yeah, both are too long. The word norm is nice and short, but not very descriptive. Ah well, my arm's getting tired from painting this shed :)

(But what I'd love to hear what people think about my suggestion of skipping holes and even of doing real unicode char length)

# Bill Frantz (12 years ago)

On 11/23/11 at 10:31, axel at rauschma.de (Axel Rauschmayer) wrote:

Please keep the general js api consistent.

A foolish consistency...

We also use 'hasOwnProperty' and 'forEach' and 'toLocaleString' in JS. Why not use those names? Because it's not the same operation. Neither is it the same thing as .length. An array is a sequential data structure, so it uses .length. A map and a set is not a sequential data structure, so it should not.

I do get the point, though: Whatever is introduced should be supported consistently. But that is already in the works, if arrays will indeed have the same size/cardinality-related property as collections.

The negative example is Java, where you have length, length(), size() and many other things. JavaScript is still fairly uniform, with the DOM being the exception.

<rant>

I did a lot of Java programming 10 to 15 years ago. Most of the pain has subsided into distant memory, but the pain of different method names used to find out how many objects are currently in a collection is still fresh in my memory.

I "duck classify" all objects which store "things" and later give them back without using or modifying them as "collections". Collections include arrays, sets, bags, b-trees, hash tables, etc.

Please give me one way of finding out how many "things" are in a collection so I don't have to remember what "language lawyer" interpretation defined this particular collection's method name.

(I survived the Algol68 report. If you want to have only one precise meaning for a word, don't borrow one from a natural language. Otherwise just accept that in technical usage, a word's meaning(s) may be only loosely connected to its natural language meanings.)

</rant>

Cheers - Bill


Bill Frantz |Security, like correctness, is| Periwinkle (408)356-8506 |not an add-on feature. - Attr-| 16345 Englewood Ave www.pwpconsult.com |ibuted to Andrew Tannenbaum | Los Gatos, CA 95032

# David Herman (12 years ago)

On Nov 23, 2011, at 3:17 PM, Bill Frantz wrote:

I did a lot of Java programming 10 to 15 years ago. Most of the pain has subsided into distant memory, but the pain of different method names used to find out how many objects are currently in a collection is still fresh in my memory.

Fair enough.

I "duck classify" all objects which store "things" and later give them back without using or modifying them as "collections". Collections include arrays, sets, bags, b-trees, hash tables, etc.

I do too. To me "size()" felt natural: it's the closest to the way I would say it common speaking: "get the size of the collection." (I'm okay with "count()" too, but for operations that don't modify a data structure, I find it natural to name them after the result they produce rather than the action they perform. I don't talk about the "count" of a collection.)

Please give me one way of finding out how many "things" are in a collection so I don't have to remember what "language lawyer" interpretation defined this particular collection's method name.

Yay insults! I love insults.

(I survived the Algol68 report. If you want to have only one precise meaning for a word, don't borrow one from a natural language. Otherwise just accept that in technical usage, a word's meaning(s) may be only loosely connected to its natural language meanings.)

I'm just basing this on my experience. I'm used to "the number of things in this collection" being called the "size" not the "length".

Also, as someone pointed out in this thread, the length of an array is not the same as the number of indexed elements of the array, thanks to holes. So not only are the words different in English (IME, IMHO, YMMV, yadda yadda yadda) but the actual operations we're talking about are different.

# Till Schneidereit (12 years ago)

(I survived the Algol68 report. If you want to have only one precise meaning for a word, don't borrow one from a natural language. Otherwise just accept that in technical usage, a word's meaning(s) may be only loosely connected to its natural language meanings.)

I'm just basing this on my experience. I'm used to "the number of things in this collection" being called the "size" not the "length".

Also, as someone pointed out in this thread, the length of an array is not the same as the number of indexed elements of the array, thanks to holes. So not only are the words different in English (IME, IMHO, YMMV, yadda yadda yadda) but the actual operations we're talking about are different.

I agree about "size" being the right name:

  • "set count" sounds like it means "the number of sets", not "the number of elements contained in this set"

  • "set length" sounds like, well, nothing, really. And "length" is already taken and means something very different

  • "set size" sounds just about perfect

# Bill Frantz (12 years ago)

On 11/23/11 at 16:38, dherman at mozilla.com (David Herman) wrote:

I'm just basing this on my experience. I'm used to "the number of things in this collection" being called the "size" not the "length".

I'm OK with any of: length, size, count, or even numberOfThingsCollected. (I realize Brendan will object to the camel caps, and everyone will object to the verbosity of that last not-terribly-serious suggestion.)

I just want one standard name that applies to arrays and all other collections. (I realize it's hard to force future collection authors to follow our standard, but we can strongly encourage.)

Also, as someone pointed out in this thread, the length of an array is not the same as the number of indexed elements of the array, thanks to holes. So not only are the words different in English (IME, IMHO, YMMV, yadda yadda yadda) but the actual operations we're talking about are different.

So "length" does have something to do with the amount of machine storage used, although its in funny units and ignores fixed overhead and possible implementation optimizations. :-)

If we pick a word other than length, we could make it ignore holes in arrays so "foo" isn't necessarily equal to "length".

Cheers - Bill


Bill Frantz | When it comes to the world | Periwinkle (408)356-8506 | around us, is there any choice | 16345 Englewood Ave www.pwpconsult.com | but to explore? - Lisa Randall | Los Gatos, CA 95032

# Kevin Reid (12 years ago)

On Nov 23, 2011, at 13:27, David Herman wrote:

An additional point about consistency: many scripting languages talk about the "length" of a table data structure because they actually expose the representation of a table as an array or list.

I dispute your examples, as follows:

IIRC Perl/PHP associative arrays,

In Perl, hashes are different builtin objects from arrays; they merely have useful conversion behavior when used in list context (which is a call-semantics issue unrelated to data structures). The way to get the number of elements is to call 'keys %myhash' in scalar context. 'length %myhash' will do something useless. I'm not familiar with PHP.

Python dicts,

Again, different builtin objects. If they have any array nature, it is not exposed to the programmer; myDict[key] gets you a lookup by hash key, not array indexing.

Lisp alists,

An alist in Lisp is not a distinctly typed data structure at all; it is only and entirely a particular application of linked lists (which are an application of cons cells (pairs/tuples)) for which there are utility functions in the standard library. A (Common) Lisp programmer looking for the size of an alist would indeed (length my-alist), but if they had a hash table it would be (hash-table-count my-ht). (In CL, the length function applies to all sequences, but a hash table is not a sequence; there are no functions generic over all kinds of collections.)

and Ruby hashes are all transparently built from arrays or lists. But Map and Set aren't arrays, they're their own data structure. So IMO it makes sense to name their methods on their on terms, not on the terms of a different data structure.

(For what it's worth, I agree with the previous suggestion to make .length used only for things which have [0], [1], [2], …; and that if it is instead a collection with .get() and .put()/.set() or similar then .size() or .count() makes sense.)