For AI agents: the complete documentation index is available at /tc39-atlas/en/llms.txt, the full documentation bundle is available at /tc39-atlas/en/llms-full.txt, and this page is available as Markdown at /tc39-atlas/en/proposals/stage/4/proposal-iterator-sequencing.md.
  • English
  • Iterator Sequencing S4

    Proposal details
    Proposal overview

    This proposal adds a static Iterator.concat method to sequentially combine multiple iterables into one iterator. It addresses the ergonomic gap of manually using generators or helper libraries for concatenation.

    Note

    The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.

    Iterator Sequencing

    A TC39 proposal to create iterators by sequencing existing iterators.

    Stage: 4

    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 Iterator.prototype.flatMap with the identity function.

    function* selfCountingSequenceHelper() {
      for (let n = 1;; ++n) {
        yield Array(n).fill(n);
      }
    }
    let selfCountingSequence = selfCountingSequenceHelper().flatMap(x => x)

    prior art

    other languages

    languagedata typeexactly 2arbitrary
    Clojurelazy seqconcat
    ElmListappend/++concat
    HaskellSemigroup<>mconcat
    OCamlSeqappendconcat
    Pythoniteratorchain
    RubyEnumerablechain
    RustIteratorchainflatten
    ScalaIteratorconcat/++
    SwiftLazySequencejoined

    JS libraries

    libraryexactly 2arbitrary
    @softwareventures/iteratorprependOnce/appendOnceconcatOnce
    extra-iterableconcat
    immutable.jsSeq::concat
    iterablefuconcatenate
    itertools-tschain
    lodashflatten
    ramdaconcatunnest
    sequencyplus
    wuchain