Mark S. Miller wrote:


    Hmm, maybe -- but does Self have a reference-identity
    equivalence-relation operator that can't be spoofed? Might help to
    ask David, but to abstract from that particular SPLASH 2011 Q&A,
    obviously we won't be enabling such fakery in JS.


I don't get it. What are you proposing to change? It seems we have agreement on the following integrity invariants:

Relax, I'm not proposing yet, just discussing. The current sub-thread started with the "nominal types bad!" assertion. I found that provocative claim inspiring; it reminded me of the SPLASH talk Tom gave. So I asked whether we can ever extend JS to allow meta-programming such that any type could be proxied.

If so, we'd have no nominal types, but we all agree that some cases need a trademark or brand integrity test that can't be subverted. In the limit, JS would have branding when needed on top of structural types, with branding based on an identity test (David showed the mirror one for Self) that cannot be proxied.

* The object state invariants that were first codified in ES5 and further refined in the ES6 text, and that Direct Proxies were designed to enforce.

Good.

* typeof x === "number" and similar, for all the typeof strings defined in ES5, as reliable but coarse brands. typeof x === "function" does not mean that x is not a proxy, but only if its target is a function (or a proxy whose target...)

Right. I think this takes in the (typeof x == typeof y && x == y <=> x === y) two-way implication.

* Object.prototype.toString.call(x) === "[object Date]" and similar, but only those, since some legacy ES5 code depends on the integrity of those tests. For example, compromising this would introduce security holes into some Caja code. These are less coarse than typeof, still string-based and non-extensible as a branding mechanism.

The details for this item are at issue.

Array.isArray(x), where true does not mean that is is not a proxy, but only if its target is an array (or a proxy whose target...)

And Array is a nominal type, right? More below.


* === itself

* WeakMap key lookup, since this follows from preserving the integrity of ===

* A proxy's target cannot be mutated, though a revocable proxy's target can be dropped (by revocation)


So, given that we're keeping all the above, what are you proposing to weaken?

I'm not proposing to weaken anything.

The questions raised in this thread swirl around why people continue to use Object.prototype.toString.call(x) to query some larger-than-we'd-like set of nominal types. If that set can be ring-fenced, condemned as bad legacy ("bad!"), and obsoleted over deep time, then great -- but in that future, the evolved language must not enable integrity bugs based on some brand test or other that replaces O.p.toString.call.

If we could have a more definite idea of the rules then, we could do a better job finalizing toStringTag in ES6.

But this still seems too speculative right now. I agree that the bullet list you give above, _sans_ the O.p.toString.call item, *should* be enough. Yet there is room for doubt. Consider: we just amended Array.isArray to return true for a proxy whose (ultimate) target is an Array instance. Array.isArray was added to ES5 because instanceof is realm-specific because (prototype) object identity-specific.

For now it still seems that nominal types exposed via built-ins still matter in ways that can't be modeled by object identity. The answer in the future is branding, which cannot use weak maps or === or other object (reference) identity tests. ISTM we need more definite consensus on branding to finish off toStringTag in ES6.

/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to