Array.from API
On Mon, Oct 6, 2014 at 10:59 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
Hi,
We're currently polyfilling
Array.from
in our codebase following the latest draft [1]. And I was actually surprised by themapfn
being involved into the algorithm.
Have you tried es6-shim?
I mean, from the performance perspective it's probably .. ok-ish.. but from the API design perspective it feels like combining the actual transformation of an iterable (or of an array-like) with the mapping, is the "too much of responsibility" anti-pattern. Why not filter then as well? (or, as one of the comments on a diff review: "I'm actually disappointed it won't do my laundry as well :P").
It probably should be just:
Array.from(...).map(mapfn);
Unless I'm missing something, and there was a special reason to include the mapping.
Yes: rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue Any subclass of array will want to produce a list of its own "kind", but .map returns an Array. This thread is also a dup of: esdiscuss/2013-June/031500
On Mon, Oct 6, 2014 at 11:19 PM, Rick Waldron <waldron.rick at gmail.com>
wrote:
On Mon, Oct 6, 2014 at 10:59 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
Hi,
We're currently polyfilling
Array.from
in our codebase following the latest draft [1]. And I was actually surprised by themapfn
being involved into the algorithm.Have you tried es6-shim?
I mean, from the performance perspective it's probably .. ok-ish.. but from the API design perspective it feels like combining the actual transformation of an iterable (or of an array-like) with the mapping, is the "too much of responsibility" anti-pattern. Why not filter then as well? (or, as one of the comments on a diff review: "I'm actually disappointed it won't do my laundry as well :P").
It probably should be just:
Array.from(...).map(mapfn);
Unless I'm missing something, and there was a special reason to include the mapping.
Yes: rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue Any subclass of array will want to produce a list of its own "kind", but .map returns an Array. This thread is also a dup of: esdiscuss/2013-June/031500
And esdiscuss.org/topic/array-subclassing-map-and-iterables-re-jan-30-tc39-meeting-notes#content
On Mon, Oct 6, 2014 at 8:19 PM, Rick Waldron <waldron.rick at gmail.com> wrote:
On Mon, Oct 6, 2014 at 10:59 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
Hi,
We're currently polyfilling
Array.from
in our codebase following the latest draft [1]. And I was actually surprised by themapfn
being involved into the algorithm.Have you tried es6-shim?
Yeah, I'm aware of it, though, we have own versions for better performance, since may skip some internal checks, etc.
I mean, from the performance perspective it's probably .. ok-ish.. but from the API design perspective it feels like combining the actual transformation of an iterable (or of an array-like) with the mapping, is the "too much of responsibility" anti-pattern. Why not filter then as well? (or, as one of the comments on a diff review: "I'm actually disappointed it won't do my laundry as well :P").
It probably should be just:
Array.from(...).map(mapfn);
Unless I'm missing something, and there was a special reason to include the mapping.
Yes: rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue Any subclass of array will want to produce a list of its own "kind", but .map returns an Array. This thread is also a dup of: esdiscuss/2013-June/031500
I see. OK, thanks Rick, will re-read.
Dmitry
On Tue, Oct 7, 2014 at 1:48 AM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
On Mon, Oct 6, 2014 at 8:19 PM, Rick Waldron <waldron.rick at gmail.com> wrote:
On Mon, Oct 6, 2014 at 10:59 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
We're currently polyfilling
Array.from
in our codebase following the latest draft [1]. And I was actually surprised by themapfn
being involved into the algorithm. Have you tried es6-shim? Yeah, I'm aware of it, though, we have own versions for better performance, since may skip some internal checks, etc.
(Speaking as an es6-shim maintainer) I'm always interested in benchmark results and performance patches. Are the ES6-required checks really slowing you down? I would think that most JITs and CPUs handle infrequently-taken branches pretty well these days.
On Tue, Oct 7, 2014 at 6:17 AM, C. Scott Ananian <ecmascript at cscott.net>
wrote:
On Tue, Oct 7, 2014 at 1:48 AM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
On Mon, Oct 6, 2014 at 8:19 PM, Rick Waldron <waldron.rick at gmail.com> wrote:
On Mon, Oct 6, 2014 at 10:59 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
We're currently polyfilling
Array.from
in our codebase following the latest draft [1]. And I was actually surprised by themapfn
being involvedinto the algorithm. Have you tried es6-shim? Yeah, I'm aware of it, though, we have own versions for better performance, since may skip some internal checks, etc.
(Speaking as an es6-shim maintainer) I'm always interested in benchmark results and performance patches. Are the ES6-required checks really slowing you down? I would think that most JITs and CPUs handle infrequently-taken branches pretty well these days.
The es6-shim
is written well, though the performance is not the only
reason. We have own modules and polyfilling system, and don't polyfill
every single thing (just needed), so it's easier to write own.
Dmitry
On Mon, Oct 6, 2014 at 10:48 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Mon, Oct 6, 2014 at 8:19 PM, Rick Waldron <waldron.rick at gmail.com> wrote:
On Mon, Oct 6, 2014 at 10:59 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
Hi,
We're currently polyfilling
Array.from
in our codebase following the latest draft [1]. And I was actually surprised by themapfn
being involved into the algorithm.Have you tried es6-shim?
Yeah, I'm aware of it, though, we have own versions for better performance, since may skip some internal checks, etc.
I mean, from the performance perspective it's probably .. ok-ish.. but from the API design perspective it feels like combining the actual transformation of an iterable (or of an array-like) with the mapping, is the "too much of responsibility" anti-pattern. Why not filter then as well? (or, as one of the comments on a diff review: "I'm actually disappointed it won't do my laundry as well :P").
It probably should be just:
Array.from(...).map(mapfn);
Unless I'm missing something, and there was a special reason to include the mapping.
Yes: rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue Any subclass of array will want to produce a list of its own "kind", but .map returns an Array. This thread is also a dup of: esdiscuss/2013-June/031500
I see. OK, thanks Rick, will re-read.
OK, have checked. And guess I still don't see a big issue, as long as the
Array.prototype.map
preserves the kind (by delegating to new this.constructor(...)
).
That specific example like:
NodeList.form(['div', 'span'], nodeName =>
document.createElement(nodeName));
arguing that the NodeList
can't create elements from the strings doesn't
seems to me a good reason for introducing that anti-pattern, and it's
really should be rewritten as:
NodeList.form(['div', 'span'].map(nodeName =>
document.createElement(nodeName)));
And other things are better be written:
<ArrayKind>.from(iterable).map(mapfn)
Am I still missing something?
Dmitry
From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Dmitry Soshnikov
Am I still missing something?
Yes.
var uint16s = new Uint16Array([258]);
var uint8s = Uint8Array.from(uint16s, x => x / 2);
console.log(uint8s); // [129]
var uint16s = new Uint16Array([258]);
var uint8s = Uint8Array.from(uint16s).map(x => x / 2);
console.log(uint8s); // [1]
On Tue, Oct 7, 2014 at 11:46 AM, Domenic Denicola < domenic at domenicdenicola.com> wrote:
From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Dmitry Soshnikov
Am I still missing something?
Yes.
var uint16s = new Uint16Array([258]); var uint8s = Uint8Array.from(uint16s, x => x / 2); console.log(uint8s); // [129]
var uint16s = new Uint16Array([258]); var uint8s = Uint8Array.from(uint16s).map(x => x / 2); console.log(uint8s); // [1]
This seems the same "issue" as with the NodeList
. The arguments for the
from
should be anything that the constructor expects, if the NodeList
excepts a document node, it should be passed a document node, not a string.
I.e. the array should be mapped before passing to the from
.
var uint16s = new Uint16Array([258]);
var uint8s = Uint8Array.from(uint16s.map(x => x / 2));
console.log(uint8s); // [129]
Is it?
Otherwise, we can back to the question why it doesn't do filter as well?
Dmitry
On Tue, Oct 7, 2014 at 11:56 AM, Claude Pache <claude.pache at gmail.com>
wrote:
Le 7 oct. 2014 à 20:36, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
And other things are better be written:
<ArrayKind>.from(iterable).map(mapfn)
Am I still missing something?
Yes:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0))
Still seems the same as NodeList
"issue":
UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0)));
Dmitry
On Tue, Oct 7, 2014 at 11:59 AM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:56 AM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 20:36, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
And other things are better be written:
<ArrayKind>.from(iterable).map(mapfn)
Am I still missing something?
Yes:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0))
Still seems the same as
NodeList
"issue":UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0)));
And after you have fed the data the UInt32Array
expects, you can post-map
it as well:
UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0))).map(v => v * 2);
What's is wrong in here? We don't have "too much of responsibility" anti-pattern, explicitly separate the transformation form mapping, and explicitly say what the format of data a particular constructor expects (thus, mapping it before passing, as it should be).
Dmitry
On Tue, Oct 7, 2014 at 12:01 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:59 AM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:56 AM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 20:36, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
And other things are better be written:
<ArrayKind>.from(iterable).map(mapfn)
Am I still missing something?
Yes:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0))
Still seems the same as
NodeList
"issue":UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0)));
And after you have fed the data the
UInt32Array
expects, you can post-map it as well:UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0))).map(v => v * 2);
What's is wrong in here? We don't have "too much of responsibility" anti-pattern, explicitly separate the transformation form mapping, and explicitly say what the format of data a particular constructor expects (thus, mapping it before passing, as it should be).
And that's an iterable being passed to the from may not have the map
method doesn't seem to me a good reason either. Still this anti-pattern
feels worse.
Dmitry
On Tue, Oct 7, 2014 at 11:46 AM, Domenic Denicola < domenic at domenicdenicola.com> wrote:
From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Dmitry Soshnikov
Am I still missing something?
Yes.
var uint16s = new Uint16Array([258]); var uint8s = Uint8Array.from(uint16s, x => x / 2); console.log(uint8s); // [129]
var uint16s = new Uint16Array([258]); var uint8s = Uint8Array.from(uint16s).map(x => x / 2); console.log(uint8s); // [1]
Moreover, these two examples are semantically completely different. They
confuse and substitute the pre- and post- mapping. Clearly, it should be
pre-mapping here, and the second example is not even correct from this
perspective. And exactly manually pre-map it, is seems better, because that
mapfn
on the API level can simply be confusing: what does it do -- maps
pre- or post?
And as mentioned above, after the correct list is constructed (with
possible pre-mapping), developers can also post-map it calling the
Array.prototype.map
that still preserves the kind of the collection.
So I'd say, we should exclude the mapfn
from Array.from
in order to
keep the implementation (including polyfills) simpler and responsible for
only one things -- building a <ArrayKind> collection from another
collection or an iterable, consuming correct data.
Dmitry
On Tue, Oct 7, 2014 at 3:01 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com
wrote:
On Tue, Oct 7, 2014 at 11:59 AM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:56 AM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 20:36, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
And other things are better be written:
<ArrayKind>.from(iterable).map(mapfn)
Am I still missing something?
Yes:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0))
Still seems the same as
NodeList
"issue":UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0)));
And after you have fed the data the
UInt32Array
expects, you can post-map it as well:UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0))).map(v => v * 2);
What's is wrong in here?
That example will allocate 2 additional objects; the following version of the same operation will allocate zero additional objects:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0) * 2);
On Tue, Oct 7, 2014 at 12:22 PM, Rick Waldron <waldron.rick at gmail.com>
wrote:
On Tue, Oct 7, 2014 at 3:01 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:59 AM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:56 AM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 20:36, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
And other things are better be written:
<ArrayKind>.from(iterable).map(mapfn)
Am I still missing something?
Yes:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0))
Still seems the same as
NodeList
"issue":UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0)));
And after you have fed the data the
UInt32Array
expects, you can post-map it as well:UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0))).map(v => v * 2);
What's is wrong in here?
That example will allocate 2 additional objects; the following version of the same operation will allocate zero additional objects:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0) * 2);
Exactly. And this is what I mentioned at the beginning: the performance reasons shouldn't (never) overweight in "good API design" topics.
Dmitry
On Tue, Oct 7, 2014 at 12:25 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 12:22 PM, Rick Waldron <waldron.rick at gmail.com> wrote:
On Tue, Oct 7, 2014 at 3:01 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:59 AM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:56 AM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 20:36, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
And other things are better be written:
<ArrayKind>.from(iterable).map(mapfn)
Am I still missing something?
Yes:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0))
Still seems the same as
NodeList
"issue":UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0)));
And after you have fed the data the
UInt32Array
expects, you can post-map it as well:UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0))).map(v => v * 2);
What's is wrong in here?
That example will allocate 2 additional objects; the following version of the same operation will allocate zero additional objects:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0) * 2);
Exactly. And this is what I mentioned at the beginning: the performance reasons shouldn't (never) overweight in "good API design" topics.
Since the next question will be: where is filter? It allows not allocating stuff at all. However, we won't mention whether it's an anti-pattern or not, since it goes without saying.
Dmitry
On Tue, Oct 7, 2014 at 12:27 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 12:25 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 12:22 PM, Rick Waldron <waldron.rick at gmail.com>
wrote:
On Tue, Oct 7, 2014 at 3:01 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:59 AM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 11:56 AM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 20:36, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> a écrit :
And other things are better be written:
<ArrayKind>.from(iterable).map(mapfn)
Am I still missing something?
Yes:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0))
Still seems the same as
NodeList
"issue":UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0)));
And after you have fed the data the
UInt32Array
expects, you can post-map it as well:UInt32Array.from(['a', 'b', 'c].map(x => x.codePointAt(0))).map(v => v * 2);
What's is wrong in here?
That example will allocate 2 additional objects; the following version of the same operation will allocate zero additional objects:
UInt32Array.from(['a', 'b', 'c], x => x.codePointAt(0) * 2);
Exactly. And this is what I mentioned at the beginning: the performance reasons shouldn't (never) overweight in "good API design" topics.
Since the next question will be: where is filter? It allows not allocating stuff at all. However, we won't mention whether it's an anti-pattern or not, since it goes without saying.
I mean, yeah, we can accept and live with this -- aka, yeah why not, it's
convenient in place to pre-map, and good for cases when an iterable doesn't
have the map
, and it's good for performance. But all the things from
above stands: it's confusing since doesn't explain whether it's pre- or
post- map, and takes too much at implementation.
Otherwise, I think it can be there, as long as it was approved already. Worth though considering this in the future API designs: the performance shouldn't drive the API.
Dmitry
On Tue, Oct 7, 2014 at 12:32 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
I mean, yeah, we can accept and live with this -- aka, yeah why not, it's convenient in place to pre-map, and good for cases when an iterable doesn't have the
map
, and it's good for performance. But all the things from above stands: it's confusing since doesn't explain whether it's pre- or post- map, and takes too much at implementation.
Alternately, you can just consider Foo.from to be the method version of a comprehension - you can feed it any iterable and transform the value arbitrarily before putting it into the new collection. That does suggest that a filter argument would also be useful, as you've said.
On Tue, Oct 7, 2014 at 12:50 PM, Tab Atkins Jr. <jackalmage at gmail.com>
wrote:
On Tue, Oct 7, 2014 at 12:32 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
I mean, yeah, we can accept and live with this -- aka, yeah why not, it's convenient in place to pre-map, and good for cases when an iterable doesn't have the
map
, and it's good for performance. But all the things from above stands: it's confusing since doesn't explain whether it's pre- or post- map, and takes too much at implementation.Alternately, you can just consider Foo.from to be the method version of a comprehension - you can feed it any iterable and transform the value arbitrarily before putting it into the new collection. That does suggest that a filter argument would also be useful, as you've said
Yes, the list comprehensions is the thing that came to me in mind as well.
P.S> @all: Also, I apologize I posted to many replies guys above. I wish I
could edit/combine them, but can't in the email. Hope it's not considered as spam ;)
Dmitry
Le 7 oct. 2014 à 21:32, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
But all the things from above stands: it's confusing since doesn't explain whether it's pre- or post- map, and takes too much at implementation.
My previous example could have been written as: UInt32Array.from('abc', x => x.codePointAt(0))
(recalling that strings are iterable in ES6). My mapping is neither a pre-, nor a post-map. It's just a map which transforms a kind of value (a Unicode character) into another kind of value (a 32-bit integer).
On Tue, Oct 7, 2014 at 1:20 PM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 21:32, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
But all the things from above stands: it's confusing since doesn't explain whether it's pre- or post- map, and takes too much at implementation.
My previous example could have been written as:
UInt32Array.from('abc', x => x.codePointAt(0))
(recalling that strings are iterable in ES6). My mapping is neither a pre-, nor a post-map. It's just a map which transforms a kind of value (a Unicode character) into another kind of value (a 32-bit integer).
This code example is a good justification of the "an iterable doesn't have
own map
method", but other than that, it's clearly pre-mapping, since
each element of the result is mapped before being set. The code is
semantically equivalent to:
UInt32Array.from('abc'.toArray().map(x => x.codePointAt(0));
Dmitry
I think all of the above examples are trying to create a case such as
| UInt32Array.from(nodelist, node => parseInt(node.value, 10) );
where neither can nodes be stored in an Uint32Array nor integers be stored in a NodeList.
This might happen quite often, as from
seems to be the "type casting"
operator ArrayA<X> -> ArrayB<Y> type - and if we cannot rely on implicit
casting, we need a X -> Y converter function.
A go-around to the "least common ancestor" array type that can store both Xs and Ys is cumbersome. (And I'm not looking on performance, just about clarity/conciseness).
Since the next question will be: where is filter?
Good question. I guess however that since this does only concern the Y type that the ArrayB can store, it would be built-into that ArrayB<Y>
constructor that we cast to.
E.g. typed arrays are known to clamp or take modulos of the passed
values; if you really wanted to completely omit passed values you'd
rather overwrite the .from
method as a whole instead of relying on the
inherited one.
Bergi
On Tue, Oct 7, 2014 at 1:45 PM, Bergi <a.d.bergi at web.de> wrote:
I think all of the above examples are trying to create a case such as
| UInt32Array.from(nodelist, node => parseInt(node.value, 10) );
where neither can nodes be stored in an Uint32Array nor integers be stored in a NodeList.
Not sure what you mean by "nor integers be stored in a NodeList", but how does your example differ from:
UInt32Array.from(nodeList.map(node => parseInt(node.value, 10)));
Anyhow, seems the only good reason (IMO) here is "an iterable may not have
own map
method", and we can live with that. And the broken and confusing
examples (when a post-map is substituted to the place of a clear pre-map)
do not help that much. Otherwise, I'd remove the mapfn
from Array.from
(unless to turn it into a comprehensions API and accept the filter as well).
Dmitry
On Tue, Oct 7, 2014 at 2:11 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 1:45 PM, Bergi <a.d.bergi at web.de> wrote:
I think all of the above examples are trying to create a case such as
| UInt32Array.from(nodelist, node => parseInt(node.value, 10) );
where neither can nodes be stored in an Uint32Array nor integers be stored in a NodeList.
Not sure what you mean by "nor integers be stored in a NodeList", but how does your example differ from:
He meant that, assuming NodeList had a .map() that returned another NodeList (in general, assuming that .map() is type-preserving, which it's not currently), you wouldn't be able to easily do a "map it first, then translate into the new collection" - you'd have to explicitly translate it into a collection that can hold both UInt32 and Node values, then map, then translate.
UInt32Array.from(nodeList.map(node => parseInt(node.value, 10)));
This works because .map() is not type-preserving, and automatically produces an Array (which can accept anything).
On Tue, Oct 7, 2014 at 2:20 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
On Tue, Oct 7, 2014 at 2:11 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 1:45 PM, Bergi <a.d.bergi at web.de> wrote:
I think all of the above examples are trying to create a case such as
| UInt32Array.from(nodelist, node => parseInt(node.value, 10) );
where neither can nodes be stored in an Uint32Array nor integers be stored
in a NodeList.
Not sure what you mean by "nor integers be stored in a NodeList", but how does your example differ from:
He meant that, assuming NodeList had a .map() that returned another NodeList (in general, assuming that .map() is type-preserving, which it's not currently), you wouldn't be able to easily do a "map it first, then translate into the new collection" - you'd have to explicitly translate it into a collection that can hold both UInt32 and Node values, then map, then translate.
UInt32Array.from(nodeList.map(node => parseInt(node.value, 10)));
This works because .map() is not type-preserving, and automatically produces an Array (which can accept anything).
I see. Actually it doesn't work, your're correct, since
Array.prototype.map
does preserve the kind (at least in the latest
draft). And the UInt32Array.from(...)
would be consuming a nodeList, not
an array. Will the nodeList.map(node => parseInt(node.value, 10));
by
itself actually work then?
Dmitry
On Tue, Oct 7, 2014 at 2:26 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
I see. Actually it doesn't work, your're correct, since
Array.prototype.map
does preserve the kind (at least in the latest draft).
Hmm, per Rick's earlier email and rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue,
Array#map (used by a subclass) doesn't preserve the subclass's type; it always returns an Array.
And the
UInt32Array.from(...)
would be consuming a nodeList, not an array. Will thenodeList.map(node => parseInt(node.value, 10));
by itself actually work then?
If .map() is inherited from Array, and thus not type-preserving, yes, it'll work.
On Tue, Oct 7, 2014 at 2:35 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
On Tue, Oct 7, 2014 at 2:26 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
I see. Actually it doesn't work, your're correct, since
Array.prototype.map
does preserve the kind (at least in the latest draft).Hmm, per Rick's earlier email and < rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue
, Array#map (used by a subclass) doesn't preserve the subclass's type; it always returns an Array.
And the
UInt32Array.from(...)
would be consuming a nodeList, not an array. Will thenodeList.map(node => parseInt(node.value, 10));
by itself actually work then?If .map() is inherited from Array, and thus not type-preserving, yes, it'll work.
Yes, it is preserving (probably was changed since that previous
discussion), see (9) in
people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.map.
Will a simple map to node.value
on a NodeList
work with the preserving
Array#map
?
Dmitry
Le 7 oct. 2014 à 23:43, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
On Tue, Oct 7, 2014 at 2:35 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote: On Tue, Oct 7, 2014 at 2:26 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
I see. Actually it doesn't work, your're correct, since
Array.prototype.map
does preserve the kind (at least in the latest draft).Hmm, per Rick's earlier email and rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue, Array#map (used by a subclass) doesn't preserve the subclass's type; it always returns an Array.
And the
UInt32Array.from(...)
would be consuming a nodeList, not an array. Will thenodeList.map(node => parseInt(node.value, 10));
by itself actually work then?If .map() is inherited from Array, and thus not type-preserving, yes, it'll work.
Yes, it is preserving (probably was changed since that previous discussion), see (9) in people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.map. Will a simple map to
node.value
on aNodeList
work with the preservingArray#map
?
So, a SortOfArray.from
(with a mapping) is finally less confusing than a SortOfArray#map
, for you don't have to look at the doc in order to determine the type of the result... :
On Tue, Oct 7, 2014 at 4:08 PM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 23:43, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
On Tue, Oct 7, 2014 at 2:35 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
On Tue, Oct 7, 2014 at 2:26 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
I see. Actually it doesn't work, your're correct, since
Array.prototype.map
does preserve the kind (at least in the latest draft).Hmm, per Rick's earlier email and < rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue
, Array#map (used by a subclass) doesn't preserve the subclass's type; it always returns an Array.
And the
UInt32Array.from(...)
would be consuming a nodeList, not an array. Will thenodeList.map(node => parseInt(node.value, 10));
by itself actually work then?If .map() is inherited from Array, and thus not type-preserving, yes, it'll work.
Yes, it is preserving (probably was changed since that previous discussion), see (9) in people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.map. Will a simple map to
node.value
on aNodeList
work with the preservingArray#map
?So, a
SortOfArray.from
(with a mapping) is finally less confusing than aSortOfArray#map
, for you don't have to look at the doc in order to determine the type of the result... :-p
Also related, and came on Twitter just not: twitter.com/DmitrySoshnikov/status/519964146637737986
The mapping function from Array.from
considers holes (from the new TC39
"policy"), but Array#map
does not.
I guess this doc on Array.from
from MDN [1] should be fixed then:
More clearly, Array.from(obj, mapFn, thisArg) is the same as
Array.from(obj).map(mapFn, thisArg), except that it does not create an intermediate array.
Since not only they are "the same" (as we confuse/substitute pre- and post- mapping), but also the mapping function itself behaves differently.
[1] developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
Dmitry
On Wed, Oct 8, 2014 at 2:42 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com
wrote:
On Tue, Oct 7, 2014 at 4:08 PM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 23:43, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
On Tue, Oct 7, 2014 at 2:35 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
On Tue, Oct 7, 2014 at 2:26 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
I see. Actually it doesn't work, your're correct, since
Array.prototype.map
does preserve the kind (at least in the latest draft).Hmm, per Rick's earlier email and < rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue
, Array#map (used by a subclass) doesn't preserve the subclass's type; it always returns an Array.
And the
UInt32Array.from(...)
would be consuming a nodeList, not an array. Will thenodeList.map(node => parseInt(node.value, 10));
by itself actually work then?If .map() is inherited from Array, and thus not type-preserving, yes, it'll work.
Yes, it is preserving (probably was changed since that previous discussion), see (9) in people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.map. Will a simple map to
node.value
on aNodeList
work with the preservingArray#map
?So, a
SortOfArray.from
(with a mapping) is finally less confusing than aSortOfArray#map
, for you don't have to look at the doc in order to determine the type of the result... :-pAlso related, and came on Twitter just not: twitter.com/DmitrySoshnikov/status/519964146637737986
The mapping function from
Array.from
considers holes (from the new TC39 "policy"), butArray#map
does not.I guess this doc on
Array.from
from MDN [1] should be fixed then:More clearly, Array.from(obj, mapFn, thisArg) is the same as Array.from(obj).map(mapFn, thisArg), except that it does not create an intermediate array.
Since not only they are "the same" (as we confuse/substitute pre- and post- mapping), but also the mapping function itself behaves differently.
[1] developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
Never mind, as Rick and Allen clarified, they will produce the same arrays,
because of behavior of Array.from
which as a result already has a hole
converted to explicit undefined
value. Here is an example:
gyazo.com/4709305f3bde1c8ce0b02d2071a99e7f
Dmitry
On Wed, Oct 8, 2014 at 2:47 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com
wrote:
On Wed, Oct 8, 2014 at 2:42 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:
On Tue, Oct 7, 2014 at 4:08 PM, Claude Pache <claude.pache at gmail.com> wrote:
Le 7 oct. 2014 à 23:43, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
On Tue, Oct 7, 2014 at 2:35 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
On Tue, Oct 7, 2014 at 2:26 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:
I see. Actually it doesn't work, your're correct, since
Array.prototype.map
does preserve the kind (at least in the latest draft).Hmm, per Rick's earlier email and < rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue
, Array#map (used by a subclass) doesn't preserve the subclass's type; it always returns an Array.
And the
UInt32Array.from(...)
would be consuming a nodeList, not an array. Will thenodeList.map(node => parseInt(node.value, 10));
by itself actually work then?If .map() is inherited from Array, and thus not type-preserving, yes, it'll work.
Yes, it is preserving (probably was changed since that previous discussion), see (9) in people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.map. Will a simple map to
node.value
on aNodeList
work with the preservingArray#map
?So, a
SortOfArray.from
(with a mapping) is finally less confusing than aSortOfArray#map
, for you don't have to look at the doc in order to determine the type of the result... :-pAlso related, and came on Twitter just not: twitter.com/DmitrySoshnikov/status/519964146637737986
The mapping function from
Array.from
considers holes (from the new TC39 "policy"), butArray#map
does not.I guess this doc on
Array.from
from MDN [1] should be fixed then:More clearly, Array.from(obj, mapFn, thisArg) is the same as Array.from(obj).map(mapFn, thisArg), except that it does not create an intermediate array.
Since not only they are "the same" (as we confuse/substitute pre- and post- mapping), but also the mapping function itself behaves differently.
[1] developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
Never mind, as Rick and Allen clarified, they will produce the same arrays, because of behavior of
Array.from
which as a result already has a hole converted to explicitundefined
value. Here is an example: gyazo.com/4709305f3bde1c8ce0b02d2071a99e7f
However, these are two different semantics, although are both pre-mapping:
Array.from([1,,2].map(x=>x*x)); // [1, 4]
Array.from([1,,2],x=>x*x); // [1, NaN, 4]
Dmitry
We're currently polyfilling
Array.from
in our codebase following the latest draft [1]. And I was actually surprised by themapfn
being involved into the algorithm.I mean, from the performance perspective it's probably .. ok-ish.. but from the API design perspective it feels like combining the actual transformation of an iterable (or of an array-like) with the mapping, is the "too much of responsibility" anti-pattern. Why not filter then as well? (or, as one of the comments on a diff review: "I'm actually disappointed it won't do my laundry as well :P").
It probably should be just:
Unless I'm missing something, and there was a special reason to include the mapping.
Dmitry
[1] people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from