Stage 2.7
Classification: API Change
Human Validated: KW
Title: Iterator Sequencing
Authors: Michael Ficarra
Champions: Michael Ficarra
Last Presented: October 2024
Stage Upgrades:
Stage 1: 2023-09-27
Stage 2: 2024-06-21
Stage 2.7: 2024-10-08
Stage 3: NA
Stage 4: NA
Last Commit: 2024-12-03
Topics: iterators
Keywords: iterator concatenate generator
GitHub Link: https://github.com/tc39/proposal-iterator-sequencing
GitHub Note Link: https://github.com/tc39/notes/blob/HEAD/meetings/2024-10/october-08.md#iterator-sequencing-for-stage-27
Proposal Description:
Iterator Sequencing
A TC39 proposal to create iterators by sequencing existing iterators.
Stage: 2.7
Specification: https://tc39.es/proposal-iterator-sequencing/
presentations to committee
motivation
Often you have 2 or more iterators, the values of which you would like to
consume in sequence, as if they were a single iterator. Iterator libraries (and
standard libraries of other languages) often have a function called concat or
chain to do this. In JavaScript today, one can accomplish this with generators:
let lows = Iterator.from([0, 1, 2, 3]);
let highs = Iterator.from([6, 7, 8, 9]);
let lowsAndHighs = function* () {
yield* lows;
yield* highs;
}();
Array.from(lowsAndHighs); // [0, 1, 2, 3, 6, 7, 8, 9]It is also useful to be able to sequence immediate values among the iterators,
as one would do with yield using the generator approach.
let digits = function* () {
yield* lows;
yield 4;
yield 5;
yield* highs;
}();
Array.from(digits); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]We should explore how to make this more ergonomic and functional.
chosen solution
let digits = Iterator.concat(lows, [4, 5], highs);For the (rare) case of infinite iterators of iterators, use flatMap with the identity function.
function* p() {
for (let n = 1;; ++n) {
yield Array(n).fill(n);
}
}
let repeatedNats = p().flatMap(x => x);prior art
other languages
| language | data type | exactly 2 | arbitrary |
|---|---|---|---|
| Clojure | lazy seq | concat | |
| Elm | List | append/++ | concat |
| Haskell | Semigroup | <> | mconcat |
| OCaml | Seq | append | concat |
| Python | iterator | chain | |
| Ruby | Enumerable | chain | |
| Rust | Iterator | chain | flatten |
| Scala | Iterator | concat/++ | |
| Swift | LazySequence | joined |
JS libraries
| library | exactly 2 | arbitrary |
|---|---|---|
| @softwareventures/iterator | prependOnce/appendOnce | concatOnce |
| extra-iterable | concat | |
| immutable.js | Seq::concat | |
| iterablefu | concatenate | |
| itertools-ts | chain | |
| lodash | flatten | |
| ramda | concat | unnest |
| sequency | plus | |
| wu | chain |