{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