underscore icon indicating copy to clipboard operation
underscore copied to clipboard

Consider switching memoize cache to be compatible with ES6 Map/WeakMap.

Open jdalton opened this issue 10 years ago • 11 comments

At the moment the _.memoize cache is just a plain object. If we were to switch it to being a simple wrapper around the cache object (still doing the same param to string key use) but with the interface of ES6 Map, WeakMap that would allow devs to swap in ES6 Maps/WeakMaps for their cache. The thin wrapper would have an interface to mimic Map/WreakMap, so has, set, get, and optionally (delete, clear).

_.memoize could have a Cache constructor bolted on to it _.memoize.Cache to allow devs to swap it out with a Map/WeakMap or equiv shim as well.

Map/WeakMap are available on all modern browsers, node --harmony.

Thoughts?

jdalton avatar Sep 19 '14 17:09 jdalton

WreakMap

Freudian slip? ;-)

joshuacc avatar Sep 19 '14 18:09 joshuacc

LOL, Imma keep it :grinning:

jdalton avatar Sep 19 '14 18:09 jdalton

I'm a tenuous thumbs down on this. Underscore isn't a Maps library and this would be quite a rabbit hole to go down. It might be something to explore in 2.0 or 3.0 however, depending on how much code it would add.

akre54 avatar Sep 19 '14 19:09 akre54

I'm a tenuous thumbs down on this. Underscore isn't a Maps library and this would be quite a rabbit hole to go down.

I'm not saying Underscore should implement anything more than its simple cache look up as it is now. I'm suggesting it wrap it with an interface that is compatible with ES6 Map/WeakMap to allow devs to swap them out.

Related to #1841.

jdalton avatar Sep 19 '14 19:09 jdalton

sounds reasonable. might be nice to add support for a few other modern features for 2.0 too.

akre54 avatar Sep 19 '14 19:09 akre54

I'm :+1: on this one.

joshuacc avatar Sep 19 '14 20:09 joshuacc

How would the fallback work? Should we change it to using an array

megawac avatar Sep 19 '14 20:09 megawac

How would the fallback work? Should we change it to using an array

There would be no fallback. We don't change the existing value -> use as key (coerce to string) behavior. This way it's consistent in old and new environments. By adopting an interface of Map/WeakMap we allow devs to use them or shims without having to implement a complex map implementation on our end.

For exampe devs could do _.memoize.Cache = WeakMap; and _.memoize wouldn't care. It'd be all "Oh the _.memoize.Cache constructor returns a cache object with the interface I'm expecting (has, set, etc)" and would use it just as it would the basic Cache object.

It could look something like:

function Cache() {
  this.__wrapped__ = {};
}
_.extend(Cache.prototype,
  get: function(key) {
    return this.__wrapped__[key];
  },
  has: function(key) {
    return _.has(this.__wrapped__, key);
  },
  set: function(key, value) {
    this.__wrapped__[key] = value;
    return this;
  }
});

_.memoize = function(func, hasher) {
  var memoize = function(key) {
    var cache = memoize.cache;
    var address = (hasher ? hasher.apply(this, arguments) : key);
    if (!cache.has(address)) cache.set(address, func.apply(this, arguments));
    return cache.get(address);
  };
  memoize.cache = new _.memoize.Cache;
  return memoize;
};

_.memoize.Cache = Cache;

jdalton avatar Sep 19 '14 20:09 jdalton

:+1:

bnjmnt4n avatar Sep 20 '14 15:09 bnjmnt4n

~Maybe depends on #2453.~

Edit: no, it doesn't.

jgonggrijp avatar May 09 '20 21:05 jgonggrijp

2.0 Should just use Map internally. No need for fancy wrappers.

jgonggrijp avatar Dec 17 '21 01:12 jgonggrijp