archives

« Bugzilla Issues Index

#2883 — Array.from still not quite polyfillable using for-of


Follow-up to bug 2083.

That bug is about being able to polyfill Array.from using a for-of loop for iteration. From my implementation:

...
// Steps 6-8.
if (items[std_Symbol_iterator] !== undefined) {
// Steps 8.a-c.
var A = IsConstructor(C) ? new C() : [];

// Step 8.f.
var k = 0;

// Steps 8.d-e and 8.g.i-vi.
for (var nextValue of items) {
...
}
...

This is not quite what the spec says, because items.[[Get]](@@iterator) happens twice rather than once. What do you think--should we do the [[Get]] once to detect, and again for the loop? Or is that too much?


Hmm..

I added the second argument to GetIterator specifically to avoid that second [[Get]] which I assumed native implementations would not want to perform. I could eliminate it (at least in this call) which would make the two [[get]]'s normative. But is that really desirable?

Wouldn't this be a more faithful translation of the spec. steps:

...
// Steps 6-8.
let usingIterator = items[std_Symbol_iterator];
if (usingIterator !== undefined) {
// Steps 8.a-c.
var A = IsConstructor(C) ? new C() : [];

// Step 8.f.
var k = 0;

// Steps 8.d-e and 8.g.i-vi.
let itr = usingIterator.call(items)
for (var nextValue of itr) {
...
}
...


On second thought, I guess that doesn't quite do it either because
for(var nextValue of itr)

is still going to do:
itr[Symbol.iterator]]()

...


...so,

you could use a while loop and explicitly check the IteratorResult objects. However, I suspect (in the long run) that doesn't optimize as easily as for-of

or,

I wonder if the best approach isn't to not try to eliminate the extra [[Get]] in the spec. and leave it up to implementations to try to decide (if they are so inclined) when eliminating the second access would be non-observable.


(In reply to comment #3)
> I wonder if the best approach isn't to not try to eliminate the extra [[Get]]
> in the spec. and leave it up to implementations to try to decide (if they are
> so inclined) when eliminating the second access would be non-observable.

I'll write a while loop. We'll just have to make sure our optimizations are generic enough that we can make the while loop as fast as the for-of loop.