Array subclassing, .map and iterables (Re: Jan 30 TC39 Meeting Notes)
Herby Vojčík
herby at mailbox.sk
Sat Feb 9 15:01:41 PST 2013
Allen Wirfs-Brock wrote:
> On Feb 9, 2013, at 2:16 AM, Claus Reinke wrote:
>
>> I am trying to understand the discussion and resolution of 'The
>> Array Subclassing "Kind" Issue'. The issue (though not its
>> solution) seemed simple enough
>>
>> class V extends Array { ... } m = (new V()).map(val => val);
>> console.log( m instanceof V ); // false :(
>>
>> and I was expecting solutions somewhere along this path:
>>
>> 1. .map should work for Array subclasses, preserving class
>>
>> 2. .map is independent of Array and its subclasses, there are lots
>> of types for which it makes sense (Sets, EventEmitters, ..)
>>
>> 3. there should be an interface Mapable, implemented by Array and
>> its subclasses, but also by other relevant classes, such that
>
> the issue is that a map function can broaden the domain of array
> elements. For example,
>
> var intArray = new Int32Array([42,85,127649,32768]); //create a typed
> array from a regular array var strArray =
> intArray.map(v=>v.toString());
>
> If intArray.map() produces a new intArray then the above map function
> is invalid. If intArray.map() produces an Array instance then you
> intArray.map instance of intArray.constructor desire won't hold. We
> can't have it both ways without provide some additional mechanism
> that probably involves additional parameters to some methods or new
> methods.
>
> The choice we agreed to, at the meeting is
>
> 1) Array.prototype.map produces the same kind of array that it was
> applied to, so:
>
> for the above example m instance of V will be true.
> intArray.map(v=>v.toSring()) produces an Int32Array. The strings
> produced by the map function get converted back to numbers.
>
> 2) If you want to map the elements of an array to different kind of
> array use<ArrayClass>.from with a map function as the second
> parameter:
>
> var strArray = Array.from(intArray, v=>v.toString());
>
> This seemed like a less invasive change then adding additional target
> kind parameters to Array.prototype.map. Also it seems like a very
> clear way for programmers to state their intent.
You chose one default, but I think it was not the simplest one.
It is good to see that map is often transforming types, so "the same
type" may not be the best default (filter is another story).
I think the best would be (it is dead simple):
- to _always_ use Array in map result
- to leave Array.from (as well as Map.from, V.from etc.) as is,
generator comprehension does the mapping for you if you wish one.
So, the examples would be
V.from(x for x in new V); // you say you want the results in V
intArray.map(v=>v.toString()); // collect them in default Array
Herby
> Allen
More information about the es-discuss
mailing list