Why does Array.from also take a mapFn?

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Jun 24 12:49:36 PDT 2013


On Jun 24, 2013, at 10:22 AM, Domenic Denicola wrote:

> From: Rick Waldron [waldron.rick at gmail.com]
> 
>> One reason is the extra allocation...
> 
>> It's not at all arbitrary: filter isn't an operation used to change the value of the items in the returned iterable.
> 
> OK, I think I see. This is because `NodeList.prototype.map` behaves differently from `NodeList.prototype.filter`: the former returns an `Array`, but the latter returns a `NodeList`. Thus we need a method of doing "`NodeList.prototype.mapAsOwnType`", which we've decided to make static and call `NodeList.from`.
> 
> Makes sense, I guess? I'll try re-reading threads and meeting notes so I can understand why `NodeList.prototype.map` returns an `Array`.
> 

It's all coming back to me now and the motivating examples are clear if we use examples with constrained element types such as Typed Arrays.

First, you normally want map and other iterative array functions to return the same type of collect it was applied to:

var smalls = Int8Array.of(34, 78, -150, 127, -3, 12);
var negatedSmalls = smalls.map(v=> -v);       //negatedSmalltalk should also be a Int8Array

but sometimes you don't

var squaredSmalls_try1 = smalls.map(v=> v*v);   //no good if result is Int8Array because many values will be truncated

var squaredSmalls_try2= Int16Array.from(smalls.map(v=> v*v));   // still no good, because intermediate array is Int8Array

var squaredSmalls_try3 = Int16Array.from(smalls, map(v=> v*v));  //the plan is for this to work.

filter, etc. doesn't have this sort of problem because the values placed in the target array are all values that were retrieved from the source array. 

Regarding NodeList.prototype.map, it doesn't currently exist and W3C will need to define it if they want it.  If if follow the Es6 design it should return a NodeList not an Array.

Allen



More information about the es-discuss mailing list