Array subclassing, .map and iterables (Re: Jan 30 TC39 Meeting Notes)
Rick Waldron
waldron.rick at gmail.com
Sun Feb 10 11:18:53 PST 2013
On Sun, Feb 10, 2013 at 4:33 AM, Claus Reinke <claus.reinke at talk21.com>wrote:
(snip)
>
>
> How would use produce an Array of strings from an Int32Array?
>>
>
> Somewhat like
>
> Array.from( int32Array ).map( (elem) => elem.toString() )
>
> Implementations would be free to replace the syntactic pattern
> with an optimized single pass (in more conventional optimizing
> language implementations, such fusion of implicit or explicit loops is
> standard, but even ES JIT engines -with their limited time for
> optimization- should be able to spot the syntactic pattern).
(Assuming a future where the DOM's NodeList inherits from Array)
How would you produce a NodeList from an arbitrary array of strings?
NodeList.from( [ "div", "span", "p" ], nodeName =>
document.createElement(nodeName) );
Because...
NodeList.from( strings );
Would try to make a NodeList, but with items that of a type that it
disallows, meaning:
NodeList.from( strings ).map( nodeName =>
document.createElement(nodeName) );
Would call .map() on an empty NodeList, since the string value items had
been rejected. Of course, you might argue that I could just call it like:
NodeList.from( [ "div", "span", "p" ].map(nodeName =>
document.createElement(nodeName)) );
...But the "arraylike" or "iterable" might not have a .map() method of its
own, which will cause issues if I'm in a JS-target transpilation scenario...
(function( root ) {
root.converter = function( ctor, iterable, map ) {
return this[ ctor ].from( iterable, map );
}.bind(root);
}( this ));
(just assume that |this| is the global object ;) )
>
>
> - instead of limiting to Array, .from-map is now limited to iterables
>>>
>>
Where do you see this documented? Array.from (and any subclass) accepts
both array-likes and iterables.
> (it would work for Set, which is really OrderedSet, but it wouldn't
>>> work for WeakMap)
>>>
>>
This discussion is irrelevant to WeakMap.
>
>> We already have Array.from that works with iterables, how does adding a
>> map function change anything related to the <ArrayClass>.from result
>> domains
>>
>
> My point was that map is far more widely useful, not limited to
> Array (Array.prototype.map), and not limited to Array construction
> from Iterables (Array.prototype.from with second parameter). Consider map
> on event emitters, on promises, on exceptions, on generators, ..
>
> I don't have an alternative solution that would cover all use cases in ES
> uniformly, because the existing solutions in other languages
> do not translate directly.
> However, I wanted to ring a warning bell that adding a different partial
> solution for every new use case is not going to scale well (especially with
> things being so difficult to change once they are in ES), and misses
> potential for writing generic library code.
>
Can you show an example of this?
> If I have to write different code, depending on whether I need to map over
> a constructed Array, an Array under construction, an Array or an
> Int32Array, a generator, a promise, etc., then that will result in
> duplicate code instead of generic code.
>
>
> With a general solution to the issue, I would expect to write
>>>
>>> SubArray.from( iterable ).map( val => val ) instanceof SubArray
>>>
>>
>> yes, the above will produce an instance of SubArray. But the above also
>> has the cost of an extra copy and the map function
>> doesn't get to see the original iterable's values.
>>
>
> Implementations can fuse .from().map() as well as .map().from();
>
.from() is a static method, so .map().from() won't work.
> if you want access to the unconverted elements, you want to map
> over the iterable, not the resulting Array (again, with loop fusion
> in the implementation):
>
> SubArray.from( iterable.map( val => f(val) ) )
>
The from-map-function does map over the iterable, not the resulting Array
(or SubArray, or NodeList or whatever)
(See NodeList example above)
> Of course, since map isn't part of a standard Array-independent
> interface, I have to write that as a generator expression (not sure
> whether I'm up to date on their syntax) instead of a map.
>
> SubArray.from( (for ( elem of iterable ) in f(elem) ) )
So... you'd get a "SubArray" whose elements where the result of `(for (
elem of iterable ) in f(elem) )`, but that's the same as:
SubArray.from( iterable, f );
...Which is much nicer to read.
Rick
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130210/5e5bf56f/attachment.html>
More information about the es-discuss
mailing list