docs: function transducingIterator(collection, xform) {
    const stepReducer = {
      [p.step]: (xiter, input) => {
        const value = isKvFormObject(input) ? { [input.k]: input.v } : input;
        xiter.items.unshift(value);
        return xiter;
      },
      [p.result]: value => value
    };
  
    const iter = iterator(collection, null, true);
    const xf = xform(stepReducer);
    let reduced = false;
  
    return {
      // This array is the key to working properly with step functions that return more than one value. All of them are
      // put into the items array. As long as this array has values in it, the `next` function will return one value
      // popped from it rather than running the step function again.
      items: [],
  
      // This object is an iterator itself, so just return this. This function serves to make the iterator work right in
      // ES2015, so it can be used in for...of expressions, for instance.
      [p.iterator]() {
        return this;
      },
  
      // The next function here is rather simple. If there is already something in the items array, it's returned. If not,
      // the step function is run and, if that results in a value in the items array, it's returned. Otherwise an object
      // with {done: true} is returned.
      next() {
        if (this.items.length === 0) {
          this.step();
        }
        if (this.items.length === 0) {
          return {
            done: true
          };
        }
        return {
          value: this.items.pop(),
          done: false
        };
      },
  
      // This is where most of the work happens. It gets the next value from the input collection and runs it through the
      // reduction step functions. If that results in a value, it's given to the stepper object (which adds it to the
      // items array); otherwise the while loop continues to the next element of the input collection. This ensures that
      // there's something for the `next` function to return each time it's called.
      //
      // If the collection has finished or if the step function returns a completed object (which take will do after its
      // limit of elements has been reached, for instance), the iteration is finished by calling the result function.
      step() {
        const count = this.items.length;
        while (this.items.length === count) {
          const step = iter.next();
          if (step.done || reduced) {
            xf[p.result](this);
            break;
          }
          reduced = isCompleted(xf[p.step](this, step.value));
        }
      }
    };
  }