On Jul 10, 2011, at 4:01 PM, Brendan Eich wrote:

> On Jul 10, 2011, at 3:54 PM, Brendan Eich wrote:
> 
>> On Jul 10, 2011, at 3:02 PM, David Herman wrote:
>> 
>>>>> I'm not sure what Array.prototype methods would or wouldn't work on 
>>>>> instances of SubArray.
>>>> 
>>>> All of them.  They are all generic.
>>> 
>>> We're speaking too broadly here. It depends on what we want to work how. 
>>> For example, .map can't magically know how to produce a SubArray as its 
>>> result if that's how SubArray wants it to work.
> 
> 
> This is the real concern, I believe. The Array methods (all generic in that 
> they take array-like |this| -- at least one is Array-specific in argument 
> handling: concat) that return a new array always make an instance of Array.

This is something that is one my list to cleanup as part of my [[Class]] reform 
effort: 
http://wiki.ecmascript.org/doku.php?id=strawman:es5_internal_nominal_typing 


> 
> Alex Russell brought up the idea of extending these array-producing methods 
> to call a user-defined constructor. We discussed doing it by reflecting on 
> this.constructor, but that is not a compatible change: people today call 
> Array.prototype.slice.call(arguments) intending to get an Array instance 
> whose elements come from the arguments object. It would be wrong to change 
> this code to return a new Object, but that's what reflecting on 
> this.constructor would do, because:

My thinking was to make allow to have such methods look for a specific instance 
property (Smalltalk called its "species", but we might want to use a private 
name) whose value is the constructor to use to create the private name.

The default value of the property would be Array.  Same if it was missing.  For 
example:

const augmentedArrayProto = {
   species: AugmentedArray,
   ...
};
function AugmentedArray (...args) {
   return augmentedArrayProto <| [...args]
};

The main problem with this approach is that the developer has to explicitly 
decide to do so.  However, if isn't clear that there is an "automatic" scheme 
that would preserve backwards compat.  Also, if you actually are create a new 
kind of Array-like collection this is probably something you do want to think 
about as you don't necessarily always want to produce the same kind of 
collection as the this value.


> 
> js> function f(){return arguments.constructor}
> js> f()
> function Object() {[native code]}
> 
> So we have two choices:
> 
> 1. Duplicate the array methods with new twins mutated to reflect on 
> this.constructor -- this is ugly and bloaty, even if we can segregate the 
> methods so as to avoid mangling the twins' names.

I've considered providing an Array.extensiblePrototype object that would be a 
better [[Prototype]] than Array.prototype for new collections. However, I 
always concluded that it would just create confusion.  It would be better to 
take the "species" approach which is a target solution to a specific problem.

> 
> 2. Add a new protocol, perhaps enabled by setting a well-known private name 
> object (i.e., a unique public name), denoted it kResultConstructor, so that 
> the methods can detect something like this[kResultConstructor].
see above
> 
> (2) adds a bit of runtime cost to the methods, which are not super-optimized 
> in many way in today's engines. Not sure that hurts it much, compared to (1).

Except for very small collections, this extra indirection should be a small 
overhead compared to the actual cost of processing the collection.


> Do modules help us make a better, less bloaty form of (1)?
> 
> /be
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to