Basically, I have a use-case where I would like to use primitives to store weak references to non-primitive values. If the value is no longer referenced anywhere else, then the entry should be GC'd from the WeakMap and checking the primitive key for an existing value would return false.

Is this possible to implement, and how so in a theoretical sense? If not, why isn't it possible to?


Since people seem to be confused about the use-case, it's pretty straight-forward. Essentially, consider a function, when given a primitive, generates a non-primitive deterministically using an expensive operation. I expect a fair amount of these generated non-primitives to be used at run-time, and a large percent of them to be re-used.

For the non-primitives that have a reference held onto them, they are used as keys in an operation that coerces them back into the primitive that was used to generate them (this step cannot be avoided, unfortunately), that then must be used to re-generate the non-primitive again.

It would be convenient to have a WeakMap to access the original non-primitive, if it has already been made, instead of using the expensive operation to generate a copy of it, but currently I don't see a way to achieve this.

  • $\begingroup$ Well, my initial thought (from an object-oriented point of view) is that it's impossible, since having the value referenced by a key that can be recreated at any point non-deterministically will never be garbage collected. So, in my instance, I can see why JavaScript does not allow WeakMaps to have primitive keys $\endgroup$ – Patrick Roberts Jul 10 '17 at 5:24

Okay. My confusion with this question is that I assumed that what you wanted is a weak value map, which it appears is what you want, and this can be implemented in a straightforward manner (at least as straightforward as a weak key map). I'm using (slightly modified) terminology from Designing Efficient and Safe Weak References in Eiffel with Parametric Types. The JavaScript WeakMap is indeed a weak key map, and, as you seem to understand and D.W. states, it makes no sense to have weak references to primitive values, and thus primitive values as keys in a weak key map.

As far as a weak value map, it's implemented basically the same as a weak key map. For example, for a mark-sweep GC, during the sweeping phase if the GC notices that a value in a weak value map is dead it removes all entries in the map referencing it. A weak key map is basically the same only it considers the keys. The Eiffel paper also talks about weak vectors and doubly weak maps where either the key or the value dying results in the entry being removed.

A weak reference primitive as described in the paper or as in e.g. Java's WeakReference would make this a straightforward exercise. You'd just wrap a Dictionary<Key, WeakReference<Value>> to clean out entries on access, say.

  • $\begingroup$ Thank you for this thorough explanation. I apologize for the confusion in terminology, as I was not aware that using the term "WeakMap" was ambiguous. Anyway, now I plan to look into a Node C++ addon for weak value maps. $\endgroup$ – Patrick Roberts Jul 10 '17 at 6:43
  • $\begingroup$ @PatrickRoberts A weak key map is the more common thing, e.g. Java's WeakHashMap, so this was somewhat a mis(mis?)interpretation on my part, though I will say for the future if you are considering a concept as it appears in some particular language (in this case JavaScript) even if that's not the language you are ultimately targeting, you should make that clear. $\endgroup$ – Derek Elkins left SE Jul 10 '17 at 6:57
  • $\begingroup$ I was more curious about the theoretical perspective though. I figured if I posted something like this on stackoverflow pertaining specifically to JavaScript, it'd be downvoted and answered immediately with "no this is impossible", which I had already figured, but was unsure if this applied in general, or just non-natively in JavaScript. $\endgroup$ – Patrick Roberts Jul 10 '17 at 7:00

It would be pointless to have a primitive as the key in a Javascript WeakMap, as you can't/don't garbage-collect primitives, and a WeakMap is entirely about whether or not GC will garbage-collect the keys in the WeakMap. No purpose would be served by allowing the key to be a primitive.

See also https://softwareengineering.stackexchange.com/q/324345/34181.

  • $\begingroup$ I disagree with "It would be pointless" and "no purpose would be served". I understand that the current implementation of WeakMap holds weak references to the keys, but I'm asking if it's possible, (preferably non-natively, in any language, but this is not necessary if the explanation is generic enough), to implement a WeakMap that holds weak references to the values. If you would like, I can pose my use-case, but it would make the question a lot more lengthy. Otherwise, just assume that there is indeed a purpose to doing so. $\endgroup$ – Patrick Roberts Jul 10 '17 at 5:51
  • $\begingroup$ You wouldn't garbage collect the keys anyway, because new objects equal to those keys could be created at any time. I think this is about the values, which we don't want to keep alive just because they are in a map where they can be looked up. For example a map mapping customer id -> customer, and a customer object shouldn't stay alive just because it is in that list. $\endgroup$ – gnasher729 Jul 10 '17 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.