proposal-async-iterator-helpers icon indicating copy to clipboard operation
proposal-async-iterator-helpers copied to clipboard

How will `flatMap` handle `undefined` returns?

Open benlesh opened this issue 1 year ago • 6 comments

I'm a little fuzzy on how this (or iterator helpers) will handle undefined returns. Array#flatMap will just add an undefined value to the output flattened array. I assume the same is true here?

const result = someAsyncIterator.flatMap(v => { });

for await (const value of result) {
  console.log(value); // just prints `undefined` over and over.
}

benlesh avatar Mar 19 '24 22:03 benlesh

It throws if the mapper returns any non-iterator/iterable value, including undefined. (As a separate special case, it also throws if the mapper returns a string.)

You can try it today in Chrome 122+: [0].values().flatMap(x => [1, 2]).toArray().

bakkot avatar Mar 19 '24 22:03 bakkot

(For async helpers, it will await the value first, and also allows async iterables. But otherwise it's the same, and since await undefined is not an iterator nor a sync or async iterable, it will throw.)

bakkot avatar Mar 19 '24 22:03 bakkot

It's unfortunate that mapper returning a string will error out, i.e. that flatmap works on almost all iterables but not all of them

conartist6 avatar Mar 19 '24 23:03 conartist6

I would consider that an intentional design decision; it's very harmful that strings are directly iterable and in new APIs we're generally requiring the iterable to be an object specifically to exclude strings.

ljharb avatar Mar 19 '24 23:03 ljharb

That's very much intentional. See discussion in https://github.com/tc39/proposal-iterator-helpers/issues/244, https://github.com/tc39/proposal-iterator-helpers/issues/229, etc.

Wanting to treat a string as iterable for purposes of flatMap is such a weird thing to do that it seems fine/good that you have to explicitly signal that you really did intend to do so (e.g. by returning string[Symbol.iterator]()) rather than it happening by default.

In any case, that's off-topic for this issue.

bakkot avatar Mar 19 '24 23:03 bakkot

Oh I'm sure it's intentional, yeah. I understand why too. Sorry, I swear I'm not trying to stir up controversy everywhere I go today.

conartist6 avatar Mar 19 '24 23:03 conartist6