Private Slots

Allen Wirfs-Brock allen at
Tue Jan 15 17:00:17 PST 2013

On Jan 15, 2013, at 3:46 PM, Mark S. Miller wrote:

> On Tue, Jan 15, 2013 at 3:27 PM, Allen Wirfs-Brock
> <allen at> wrote:
>> On Jan 15, 2013, at 3:18 PM, Mark S. Miller wrote:
>>> On Tue, Jan 15, 2013 at 3:03 PM, Allen Wirfs-Brock
>>>> To start with, WeakMaps uses ephemeron algorithms
>>> Not those with the hint. That's the point. Are you getting my
>>> messages? Are they unclear? Please ack even if you have no other
>>> response. Thanks.
>> Sorry, where is this hint proposal described?
> My message in this thread at 1:54pm. Quoting
> Independent of this hint, wm.set(key, value) needs to make value
> reachable if wm *and* key are reachable. In the absence of this hint,
> to assess the space complexity of an algorithm expressed using
> WeakMaps, we may assume that the value is not made reachable any
> longer than that[1]. With the hint, we may only assume that the value
> does not outlive the key. It may very well outlive the WeakMap. This
> allows an implementation to use exactly the same implementation
> techniques internally for these wimply weak maps that we expect them
> to use for private symbols.
> [1] if not otherwise reachable of course

Ok, this paragraph was so dense I didn't realize it was the proposal...

Let me see if I can interpret.  For situations like branding where the "has" method is really all we care about you would implement the weak map as an inverted data structure.  The WM itself would have no internal state. It is primarily an identify holder that the WM method can be invoked upon. Instead, /every/ object that might to stored in such a WM must have as part of its internal state a set whose member are the WM objects that logically hold that object as a key.  The WM "set" and "has" method are implemented as:
    set(key, dontCareAboutValue) { $internalWMSet(key).set(this)}
    has(key) {return  $internalWMSet(key).has(this)}

where $internalWMSet(obj) is an internal method that provides access to an encapsulated implementation level set object.

So, yes, this casts this use case of WeakMap into a mechanism that is conceptually similar to how private Symbols would be used for branding.  But, at the expense of a lot more low level complexity in every object.  Basically every object must carry as part of its state an internalWMSet (or the ability to dynamically acquire one when it is needed). An implementation might be able to use the normal per object property store for the internalWMSet but to do so it would have to internally allow WMs to be used as property keys and then to filter them out from any normal property access or reflection operations. 

Of course, ephemeron-based WM would still have to exist to deal with situations where circular dependencies between keys and values are possible.

At the implementation object model level this all seems much more complex than having non-reflected private Symbols. If we actually want implementations to do this, we would almost surely have to explicitly specify such as I have a hard time believe that any implementor would on their own decide to do this.

Conceptually, this scheme allows people to exclusively reason about their abstractions in terms of Weakmaps.  However, I don't see that as any sort of advantage.  Per-property WeakMap side tables could be used to represent all object properties.  But who wants to think about object instances as a bunch of tables joined by a common key.  

So, for me, this further demonstrated that the combination of WeakMaps to handle circular registry dependencies and private Symbols to handle high integrity per instance state is probably exactly the right combination of features to be providing.

>> Regardless, the original request for information about the GC impact of using WeakMaps was presumably based upon the accepted WeakMap semantics.
> Are space reclamation expectations semantic? We never decided to make
> them normative. If we do, then yes. But the hint still has no
> semantics beyond their space reclamation semantics. This arguably make
> the hint simpler than private symbols.
> A note to avoid misunderstanding:
> I have been very careful in this thread not to advocate that we drop
> private symbols. But if we keep them, it should be on grounds other
> than performance. I am arguing here only that the performance argument
> is a red herring.

I believe that pragmatic performance implications are a fine thing to factor into our design decisions.  We are unlike to specify specification space reclamation requirements but that doesn't mean we don't care or don't expect implementors to make their best effort to be space efficient.  In particular we shouldn't specify things that we don't have a reasonable expectation that in can be implemented reasonably efficiently by a typical ES implementor.

I think it is fine to argue that no reasonable ES implementor is likely to spontaneously decide to implement WMs in the manner you describe above. If we want that behavior we will have to specify it, and that isn't simpler than private symbols.


More information about the es-discuss mailing list