rtfeldman / seamless-immutable

Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.
BSD 3-Clause "New" or "Revised" License
5.37k stars 195 forks source link

Generator Support? #96

Closed strawbrary closed 8 years ago

strawbrary commented 8 years ago

Hello, I'm attempting to use an immutable array with map and a generator function but the map function doesn't seem to be called.

const co = require('co');
const Immutable = require('seamless-immutable');

const printNativeGenerator = function*() {
  const arr = [1, 2, 3];
  yield arr.map(function*(n) {
    console.log(n);
  });
};

const printImmutableGenerator = function*() {
  const immutableArr = Immutable([4, 5, 6]);
  yield immutableArr.map(function*(n) {
    console.log(n);
  });
};

const printImmutableMutableGenerator = function*() {
  const immutableArr = Immutable([7, 8, 9]);
  yield immutableArr.asMutable().map(function*(n) {
    console.log(n);
  });
};

co(printNativeGenerator);
co(printImmutableGenerator);
co(printImmutableMutableGenerator);

The output for this is 1 2 3 7 8 9. So the native array and the mutable array work, but not immutable. Is it expected that you must call asMutable() to use map with a generator or would you be open to adding support for them? Thanks.

tusharmath commented 8 years ago

I don't think there is anything here that seamless-immutable should be concerned with. The co module handles generators specially and that's why it works for the other two cases. If the module realises that the returned value is an generator then it will start iterating over it.

In the printImmutableGenerator what happens is the map function iteratively converts the value (generator) into an immutable, which obviously your co module doesn't understand.

So the solution is to use the native map function on the immutable —

const printImmutableGenerator = function*() {
  const immutableArr = Immutable([4, 5, 6]);
  yield Array.prototype.map.call(immutableArr, function*(n) {
    console.log(n);
  });
};

OUTPUT: 4, 5, 6

strawbrary commented 8 years ago

Ah sorry my mistake. Thanks for helping me out and that great explanation @tusharmath.