July 26, 2012 TC39 Meeting Notes

Tom Van Cutsem tomvc.be at gmail.com
Wed Aug 1 06:07:23 PDT 2012

2012/7/31 David Bruant <bruant.d at gmail.com>

> 2012/7/31 Tom Van Cutsem <tomvc.be at gmail.com>
>> I'm open to the idea of just not trapping private names (it would
>> certainly simplify things), but like any part that proxies cannot
>> virtualize, what would be the implications on self-hosting APIs? Of course,
>> since private names don't yet exist, APIs such as the DOM do not make use
>> of it.
> To some extent, we can say that they do. dom.js uses _properties to
> discriminate what's private. So, that's where they use private names if
> they had them. It certainly gives a good sense of where private names would
> be used in a self-hosted DOM. Other libraries use that convention
> (especially in Node.js from what I've seen), so that could give an idea.

So there you have it. Good observation!

> [...]
> I think I missed the *Name trap design in the notes.
> Returning [name, value] looks very heavy to me. If you know a secret once
> and can prove it once, you can know it and prove it forever (and very
> likely will), so the API should take that property into account.
> One idea would be to have a particular property in handlers, like
> "knownPrivateNames" (which could smartly be expected to be an ES.next Set,
> or more accurately a WeakSet if this one ever gets mentionned in the spec)
> and whenever an *Trap returns for a particular private name, the after-trap
> checks whether you have the private name in your knownPrivateNames set.
> That should be enough to prove you know the secret. When you get to a new
> private name, put it in the knownPrivateNames set.
> Even in the "return [name, value]" design, one needs to store known
> private names somewhere anyway and it'll likely be on the handler anyway
> too :-) So it may be a good idea to make this storage "official" and make
> it a tool to communicate with the JS engine.
> Maybe the details I propose are not perfect, but I think there is a
> game-changer in the idea of a handler being able to share with the JS
> implementation which secrets it knows.

I don't like it. It introduces mutable state into the proxy-handler
protocol, which is currently fully functional. The proxy makes a minimum of
dependencies on the handler's behavior, and only interacts with it via
property access of trap names (crucial for double lifting). Also, since a
handler's properties may be mutable, you have to account for the fact that
a trap can be updated, thus there is the potential issue of the handler's
internal state growing out of date.

It may very well be that handlers will often need to resort to WeakMaps to
track additional state, but I'd prefer that to be explicit in the code
rather than buried implicitly in the Proxy API.

>  AFAICT, the only two useful things a handler can do when it intercepts a
>> private name it knows nothing about is:
>> 1) ask the proxy to forward
>> 2) throw
> Interestingly, you do not mention the public counterpart here :-) Digging
> a bit deeper, from a trap point of view, if you get to know 2 unique names
> for which you don't know the private part,

Hold on, terminology check: unique names wouldn't have a private part. For
any unique name n, n.public === n.

> then I don't think you can make any use of this information. Can you do a
> more relevant choice (forward or throw) based on the different unique name
> identities? I can't think of any now. From a trap point of view, you just
> have 2 unique, unforgeable and useless tokens, you can differnciate them
> thanks to identity, but that's as far as it gets, so I agree with your
> analysis here.
> Certainly trapping for private names, if it's to offer these two choices,
> is valuable, so I take back the idea of not trapping for private names. But
> I think i would take a different direction for the trap design. Combined
> with the above idea of sharing a knownPrivateNames set with the JS engine,
> what could happen is the following:
> 1) regular get/set/delete/... traps even for unique names and private
> names you have proven to know (since you have proven to know the private
> name, they are passed directly, no need for a public counterpart)
> 2) *Name traps when you don't know the private name. This trap doesn't
> have the public part as argument (since there is no use for it) but still
> leaves you the 2 choices of asking to forward or throwing.
> What do you think?

Part of the reason why we decided to fork the regular traps into additional
*Name traps is that we wanted to keep the "type signature" of the existing
traps unmodified. Your proposal 1) would change the type of the "name"
argument from String to (String | Name). So a programmer might still need
to do a case-analysis in the body of each trap.

With the split traps, the old traps continue to work fine with Strings. The
*Name traps work with both private and unique names. If a *Name trap wants
to distinguish between private/public names, it can. But the beauty of the
|name.public === name| trick for unique names is that all unique names can
be effectively treated as private names (Liskov substitutability), so a
case-analysis is not always needed.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120801/2e0b80bb/attachment.html>

More information about the es-discuss mailing list