{Weak|}{Map|Set}

Kyle Simpson getify at gmail.com
Thu Sep 15 09:24:40 PDT 2011


> You say "and you're searching for them in JS (as I was)". Had the 
> abstraction been called ObjectMap or ObjectRegistry, would you have found 
> it?

I don't think the API name is the only way someone can discover what they're 
looking for. Proper documentation for "ObjectMap" which said "keyrefs are 
held weakly" or something to that respect would probably have ended up on my 
search radar.

Of course, if the WeakMap really was both weak-key and weak-value, then I'd 
absolutely expect the name to be WeakMap (I think "weak" in this case is a 
useful and non-trivial part of the behavior). So my complaint is not "Weak", 
but that "Weak" implies something more comprehensive than is actually the 
case. It over-promises and under-delivers, so to speak.

I should also clarify my process for how I found this API (I over-simplified 
in my previous email). I actually started out with both the weakref need AND 
the object-as-key ("map") need. For the object-as-key need, I had already 
constructed a dual-numerically-indexed-array solution to associating an 
object with a value. But then, realizing that this was not only clunky, but 
also was going to make manual GC (that is, cleaning up the entries if the 
object is removed) also more awkward/less performant, I started looking for 
an API that would do both: Map (object-as-key) and automatically clean up 
the entries in the Map if either the key-object or the value-object (in my 
case, both DOM objects) were GC'd.

In that context (and in support of Allen's early assertions), "Map" in the 
name was most important to focus me into a (theoretical) class of APIs (if 
there were indeed several different kinds of maps). Then I would have 
searched through the documentation to see if any of the Maps had the "weak" 
behavior I was looking for.

OTOH, had I *only* been looking for pure Weak References, and not a Map 
structure, then I'd have been looking for some API like "WeakRef", and 
actually "Map" probably would have been confusing or ignorable noise.


> As it was, you found the right thing to look at and think about, but you 
> needed to read more before you understood whether it serves your actual 
> purpose.

I found it because a fellow Mozilla dev said "hey, that sounds like 
WeakMaps" and I thought "awesome, ask and ye shall find". Of course, the 
devil was in the details, because it wasn't actually what I needed 
completely. This was compounded by the fact that the MDN documentation (at 
least at the time) was ambiguous and didn't make it clear that only keys 
were "weak". So a well-experienced co-worker and the documentation BOTH were 
confused (as were several others through various IRC chats) as to exactly 
what was and was not "weak" in the WeakMap.

How did I figure it out? By writing it into my code, and then seeing 
mem-leak tests fail. Thankfully, I eventually found some IRC people who 
clarified that what I was seeing was not a bug but was in fact by-design. 
But, that's a hard way to learn the lesson.

Would a more accurate name have helped? Perhaps. "WeakKeyMap" certainly 
would have made it obvious that the Map was not fully "weak". Would more 
accurate documentation have helped? Absolutely. Would naming *and* 
documentation have helped other co-workers not be misled and consequently 
point me in the wrong path? I hope so.


> That's why I like "WeakMap" best -- it is the mapping that is weak, not 
> the keys or the values.

I understand what you're saying here. But as I mentioned before, the way my 
(far less informed) brain thinks about it, the "map" or "link" between two 
objects should in fact be weak and ephemeral enough that either side going 
away (being GC'd) should be enough to cause the link between the two to be 
cleaned up. I think it's because I tend to think of "Map" as more 2-way than 
one-way, though I understand it's technically only 1-way.

Saying it a different way... if the focus is on the map or link itself, and 
the RHS thing the map/link is pointing to is no longer valid/defined, then 
what use is there keeping a link that points to something now undefined?

It just seems a little unfortunate/misleading to me that from an 
implementation perspective, creating the map/link is sufficient to prevent 
the RHS value in question from ever getting to that "undefined" state. When 
I create a reference using variables/properties, I *expect* a hard reference 
that behaves like that. But when I use a specialized API with "Weak" in the 
name, I definitely expect the opposite.


--Kyle




More information about the es-discuss mailing list