I've written a utility library that provides extends of Map, Set, WeakMap and WeakSet that do only one thing: add a put(key, value):value method because returning this has been a long-time-ago battle of mine, suggesting chaining was the wrong returning type for those primitives, but I wonder if there's still hope for such simple addiction to ECMAScript.
Background
getOrInsert and getOrInsertComputed are great but not enough and not CPU/RAM friendly:
getOrInsertassumes the value has been computed anywaygetOrInsertComputedrequires allocation for a callback when inlined
Meet put(...) !!!
Put
Specifications are deadly simple:
- it adds an entry and returns its value instead of the reference itself
const obj = map.get(ref) ?? map.put(ref, stuff(ref));
const other = set.has(ref) ? ref : set.put(stuff(ref));
For Weak/Map like operations it never requires a runtime function yet it does branch around possible JIT optimizations while for Weak/Set like operations it allows to work on an item before storing it internally.
The current counter-part would require bind or other operations that cannot be ignored while executing:
const obj = map.getOrInsertComputed(ref, () => stuff(ref));
// useless CPU/RAM/GC operations ^^^^^^^^^^^^^^^^
const other = set.has(ref) ? ref : (set.add(stuff(ref)), ref);
// not really DX friendly ^^^^^^^^^^^^^^^^^^^^^^^^^^
Both are way uglier when we consider that ?? operator does a wonderful job with Weak/Map and nobody ever wanted the set reference back inline ... thoughts ?