classes and enumerability

classic Classic list List threaded Threaded
91 messages Options
12345
Reply | Threaded
Open this post in threaded view
|

classes and enumerability

Andrea Giammarchi-2
Dear Santa,
  I wish since ES3 era that properties defined on a prototype are by default **not** enumerable.

By any chance we can make this happen in ES6 classes?

Or better ... why would anyone expect or want them to be enumerable?

To define a `class` is a very explicit intent, I believe having those definitions non enumerable would be a preferred option for majority of developers that have been doomed in `for/in` since kinda ever before enumerable was not configurable.

All default methods and properties in native prototypes are **not** enumerable, why does it have to be so inconsistent with userland?

You also know ES6 is the only window we have 'cause after that it will be a breaking change.

Thank you at least for any sort of extra/concrete clarification about this choice.

Merry Christmas

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Boris Zbarsky
On 12/23/14 4:35 PM, Andrea Giammarchi wrote:
> Or better ... why would anyone expect or want them to be enumerable?

This is a good question.  Note that there is web content that depends on
the current setup wherein stuff on DOM prototypes is enumerable... you
may want to check on why exactly they do that.

I agree that it would have been better all around if none of this stuff
had been enumerable historically.  As things stand, ES builtins are
non-enumerable, DOM builtins are enumerable, and someone designing an
API and wanting to be "consistent with the platform" is screwed.

The situation is especially bad for things that start off in the DOM and
then move into ES; for example right now Gecko and Blink are not
interoperable on whether "then" is an enumerable property of
Promise.prototype...

> You also know ES6 is the only window we have 'cause after that it will
> be a breaking change.

Pretty much anything here is a breaking change, sadly, no matter what we
pick.  Certainly your proposed change is a breaking one if the intent is
that Web IDL outputs ES classes...

-Boris

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Rick Waldron
In reply to this post by Andrea Giammarchi-2


On Tue Dec 23 2014 at 7:35:44 PM Andrea Giammarchi <[hidden email]> wrote:
Dear Santa,
  I wish since ES3 era that properties defined on a prototype are by default **not** enumerable. 

By any chance we can make this happen in ES6 classes?

ES6 is done, properties of user created prototypes are enumerable by default. They can be made non-enumerable if you want them that way, but doing so by default is inconsistent with constructor function + prototype definition. 
 

Or better ... why would anyone expect or want them to be enumerable?

- Consistency with constructor function + prototype definition (severe refactoring hazard).
- Pretty useful for dynamically creating collection APIs, eg: 

  Object.keys(Servo.prototype).forEach(function(method) {
    // Create `Servos` collection class wrappers for each method
    Servos.prototype[method] = function() {
      var args = [].slice.call(arguments);
      this.each(function(servo) {
        Servo.prototype[method].apply(servo, args);
      });
      return this;
    };
  });

 

To define a `class` is a very explicit intent, I believe having those definitions non enumerable would be a preferred option for majority of developers that have been doomed in `for/in` since kinda ever before enumerable was not configurable.

All default methods and properties in native prototypes are **not** enumerable, why does it have to be so inconsistent with userland?

The widely understood, wholly well-known semantics: 

- Properties of built-in prototype objects are non-enumerable
- Properties of user defined prototype objects are enumerable by default, but can be made non-enumerable if desired.

 

You also know ES6 is the only window we have 'cause after that it will be a breaking change.

No: any future annotation syntax must allow for defining writable, configurable and enumerable attributes.

 

Thank you at least for any sort of extra/concrete clarification about this choice.



The consistency argument has won every time this conversation is brought up. There are ways to get what you want in the future (probably even in ES7), but changing the default is not the solution. 

Rick

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Glen Huang
There was some heated debate on twitter too just yesterday:
https://twitter.com/domenic/status/547146484479561730

Just wondering, is es6 class frozen? In those tweets Brendan proposed "enum in obj lit, not in class”. Looks like class is still open for modification?

On Dec 24, 2014, at 9:17 AM, Rick Waldron <[hidden email]> wrote:



On Tue Dec 23 2014 at 7:35:44 PM Andrea Giammarchi <[hidden email]> wrote:
Dear Santa,
  I wish since ES3 era that properties defined on a prototype are by default **not** enumerable. 

By any chance we can make this happen in ES6 classes?

ES6 is done, properties of user created prototypes are enumerable by default. They can be made non-enumerable if you want them that way, but doing so by default is inconsistent with constructor function + prototype definition. 
 

Or better ... why would anyone expect or want them to be enumerable?

- Consistency with constructor function + prototype definition (severe refactoring hazard).
- Pretty useful for dynamically creating collection APIs, eg: 

  Object.keys(Servo.prototype).forEach(function(method) {
    // Create `Servos` collection class wrappers for each method
    Servos.prototype[method] = function() {
      var args = [].slice.call(arguments);
      this.each(function(servo) {
        Servo.prototype[method].apply(servo, args);
      });
      return this;
    };
  });

 

To define a `class` is a very explicit intent, I believe having those definitions non enumerable would be a preferred option for majority of developers that have been doomed in `for/in` since kinda ever before enumerable was not configurable.

All default methods and properties in native prototypes are **not** enumerable, why does it have to be so inconsistent with userland?

The widely understood, wholly well-known semantics: 

- Properties of built-in prototype objects are non-enumerable
- Properties of user defined prototype objects are enumerable by default, but can be made non-enumerable if desired.

 

You also know ES6 is the only window we have 'cause after that it will be a breaking change.

No: any future annotation syntax must allow for defining writable, configurable and enumerable attributes.

 

Thank you at least for any sort of extra/concrete clarification about this choice.



The consistency argument has won every time this conversation is brought up. There are ways to get what you want in the future (probably even in ES7), but changing the default is not the solution. 

Rick
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Brendan Eich-2
It ain't over till it's over. If we can't tweak ES6 to fix a mistake,
just because process, then we're doing it wrong. OTOH the bar for any
change, including what is regarded by many (but not all) as a fix, is
very high.

We should take advantage of es-discuss to debate the crucial question,
which is not whether enumerable prototype methods are the rule or
exception -- as Rick said, for built-ins (but not all DOM methods),
non-enumerable is the common case; for user-defined classes prior to ES5
and Object.defineProperty, enumerable is the norm.

This is true in the rule/exceptions/confusion sense we all know and hate.

The question is: what should ES6 classes choose as the default? What's
the most useful default, independent of various backward-looking
consistencies? What, if the future is bigger than the past, would be best?

In the twitter thread, @wycats and I take on the idea that consistency
with object literals is required. I hope that's not controversial. Class
bodies are *not* object literals, in spite of sharing some sub-notation
(method shorthanding, mostly).

/be

Glen Huang wrote:
> There was some heated debate on twitter too just yesterday:
> https://twitter.com/domenic/status/547146484479561730
>
> Just wondering, is es6 class frozen? In those tweets Brendan proposed
> "enum in obj lit, not in class”. Looks like class is still open for
> modification?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: classes and enumerability

Gary Guo
I would say enumerate through classes' or instances' properties are a strange use and should be discouraged. I would prefer nothing but instance properties to be enumerable. To me, it is illogical for methods to be enumerable.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: classes and enumerability

Jeremy Martin

In all the discussions I've observed, the primary argument for enumerability has been consistency with ES5 prototype conventions. I don't think I've seen a single argument in favor, though, based on the actual intrinsic merits of that behaviour.

So, do such arguments exist?

On Dec 23, 2014 11:26 PM, "Gary Guo" <[hidden email]> wrote:
I would say enumerate through classes' or instances' properties are a strange use and should be discouraged. I would prefer nothing but instance properties to be enumerable. To me, it is illogical for methods to be enumerable.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Brendan Eich-2
Jeremy Martin wrote:
> In all the discussions I've observed, the primary argument for
> enumerability has been consistency with ES5 prototype conventions. I
> don't think I've seen a single argument in favor, though, based on the
> actual intrinsic merits of that behaviour.

Right, hence my tweet about "A foolish consistency". And the other tweet
against the argument-from-it's-always-been-that-way(-in-ES3-level-JS)
fallacy.

Even if you grant that enumerability is unreformable, we have to pick a
"better consistency".

It seems to me that DOM quirky enumerability of prototype methods, and
legacy ES3-ish enumerability of user-defined methods, do not sum  up to
"better'.

I tweeted several times that the legacy ES3 and below resulting in
enumerability for theprototypal-pattern's class prototype methods is a
bug not a feature.

On the DOM quirks point, built-in classes and self-hosting of built-ins
trump DOM quirks any day. Boris may have a census that argues against my
weighting, though.

Hence my support for a last-minute fix.

/be


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Kevin Smith
In reply to this post by Brendan Eich-2
The question is: what should ES6 classes choose as the default? What's the most useful default, independent of various backward-looking consistencies? What, if the future is bigger than the past, would be best?

Framed that way, then non-enumerability.

If we want to preserve any kind of conceptual integrity for enumerability, then enumerability must indicate that the property is a data element within a data structure.

Whether enumerability is worth preserving, I don't know.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Russell Leggett


On Wednesday, December 24, 2014, Kevin Smith <[hidden email]> wrote:
The question is: what should ES6 classes choose as the default? What's the most useful default, independent of various backward-looking consistencies? What, if the future is bigger than the past, would be best?

Framed that way, then non-enumerability.

If we want to preserve any kind of conceptual integrity for enumerability, then enumerability must indicate that the property is a data element within a data structure.

Whether enumerability is worth preserving, I don't know.

I'll just throw out mixins as a possible reason to keep enumerability.

- Russ 

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Kevin Smith

I'll just throw out mixins as a possible reason to keep enumerability.

I don't think enumerability really bears on mixins in ES6, because (for one) the mixin source could have symbol-named properties.  A fully-featured mixin function will need to use Object.getOwnPropertySymbols, etc.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Glen Huang
In reply to this post by Russell Leggett
Actually mixins shouldn’t be done with Object.assign if that’s what you mean.

I think the language should provide a syntax for that (e.g., Lightweight traits on http://www.nczonline.net/blog/2014/06/03/my-ecmascript-7-wishlist/)

On Dec 24, 2014, at 1:09 PM, Russell Leggett <[hidden email]> wrote:



On Wednesday, December 24, 2014, Kevin Smith <[hidden email]> wrote:
The question is: what should ES6 classes choose as the default? What's the most useful default, independent of various backward-looking consistencies? What, if the future is bigger than the past, would be best?

Framed that way, then non-enumerability.

If we want to preserve any kind of conceptual integrity for enumerability, then enumerability must indicate that the property is a data element within a data structure.

Whether enumerability is worth preserving, I don't know.

I'll just throw out mixins as a possible reason to keep enumerability.

- Russ 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Glen Huang
Although I guess it’s not very easy to desugar to es5 if there is no way to enumerate prototype methods/properties. (probably impossible?)

On Dec 24, 2014, at 1:17 PM, Glen Huang <[hidden email]> wrote:

Actually mixins shouldn’t be done with Object.assign if that’s what you mean.

I think the language should provide a syntax for that (e.g., Lightweight traits on http://www.nczonline.net/blog/2014/06/03/my-ecmascript-7-wishlist/)

On Dec 24, 2014, at 1:09 PM, Russell Leggett <[hidden email]> wrote:



On Wednesday, December 24, 2014, Kevin Smith <[hidden email]> wrote:
The question is: what should ES6 classes choose as the default? What's the most useful default, independent of various backward-looking consistencies? What, if the future is bigger than the past, would be best?

Framed that way, then non-enumerability.

If we want to preserve any kind of conceptual integrity for enumerability, then enumerability must indicate that the property is a data element within a data structure.

Whether enumerability is worth preserving, I don't know.

I'll just throw out mixins as a possible reason to keep enumerability.

- Russ 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: classes and enumerability

Gary Guo
Object.defineProperty could easily do that.

>From: [hidden email]
>Date: Wed, 24 Dec 2014 13:33:24 +0800
>
>Although I guess it’s not very easy to desugar to es5 if there is no way to enumerate prototype methods/properties. (probably impossible?)

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Glen Huang
How?

Given that you don’t know the names of the prototype properties and methods contained (could be deep in the prototype chain) in a object. How do you add these to another object?

On Dec 24, 2014, at 1:50 PM, Gary Guo <[hidden email]> wrote:

Object.defineProperty could easily do that.

>From: [hidden email]
>Date: Wed, 24 Dec 2014 13:33:24 +0800
>
>Although I guess it’s not very easy to desugar to es5 if there is no way to enumerate prototype methods/properties. (probably impossible?)


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Glen Huang
In reply to this post by Gary Guo
I guess it’s probably a misunderstanding.

I was saying that a feature like lightweight traits is probably impossible to desugar to es5, if class syntax makes properties and methods non-enum.

On Dec 24, 2014, at 1:50 PM, Gary Guo <[hidden email]> wrote:

Object.defineProperty could easily do that.

>From: [hidden email]
>Date: Wed, 24 Dec 2014 13:33:24 +0800
>
>Although I guess it’s not very easy to desugar to es5 if there is no way to enumerate prototype methods/properties. (probably impossible?)


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Kevin Smith
In reply to this post by Glen Huang
Given that you don’t know the names of the prototype properties and methods contained (could be deep in the prototype chain) in a object. How do you add these to another object?

getOwnPropertyNames, getOwnPropertySymbols, and getPrototypeOf to traverse the prototype chain.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Glen Huang
Oh, forget about those. Thanks. Then problem solved.

non-enum class syntax + trait syntax. This could make prototypal inheritance a joy to write. :)

On Dec 24, 2014, at 2:02 PM, Kevin Smith <[hidden email]> wrote:

Given that you don’t know the names of the prototype properties and methods contained (could be deep in the prototype chain) in a object. How do you add these to another object?

getOwnPropertyNames, getOwnPropertySymbols, and getPrototypeOf to traverse the prototype chain.



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Glen Huang
In reply to this post by Kevin Smith
Although when desugaring to es5, no need to consider symbol properties.

On Dec 24, 2014, at 2:02 PM, Kevin Smith <[hidden email]> wrote:

getPrototypeOf


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: classes and enumerability

Boris Zbarsky
In reply to this post by Brendan Eich-2
On 12/23/14 8:49 PM, Brendan Eich wrote:
> On the DOM quirks point

Here's the thing.  Ignoring for the moment the classes situation, it
seems to me that for "DOM" stuff specifically we have three options:

1)  Have all "DOM" prototype stuff be enumerable.  This leaves us in a
Conway's Law situation where whether stuff is enumerable or not depends
on whether the spec is written by the W3C/WhatWG or TC39.  That's where
we've been for going on two decades now, but it still sucks.

2)  Have some "DOM" stuff (whatever is currently shipping?) enumerable
but new stuff not enumerable (basically introduce a
[LegacyEnumerableProperties] or whatnot in Web IDL and sprinkle it on
everything currently shipping).  This still means we have inconsistent
behavior, but now it's inconsistent in time as opposed to organizational
structure.  And it relies on UAs being able to make this change quickly
for new APIs they add.  Gecko can do that, but I can't speak for others.

3)  Try to make all "DOM" stuff non-enumerable, dealing with compat
issues by adding [LegacyEnumerableProperties] in the few cases where
they arise.  This risks landing us in the same place as #2 depending on
how many interfaces need the annotation, plus compat fallout as we
discover which interfaces need it.  But it would maybe get us to the
point where we don't have the Conway's Law problems, and it may well
turn out that very few interfaces need the [LegacyEnumerableProperties]
thing.

If I were doing green-field implementation of the DOM, of course, option
3 it would be, to match ES builtins....

Apart from all that, we've generally been aiming at converging Web IDL
behavior on the behavior of ES6 classes as much as we can, and continue
to do so.  So if classes end up with stuff non-enumerable by default
that would militate in favor of option 3 above.  Which is great except
for the possible compat fallout.  I'm game for trying it, though, if
other UAs are.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12345