New topic regarding Proxies: intercession for ===

Tom Van Cutsem at
Thu Oct 28 07:15:35 PDT 2010

2010/10/27 Brendan Eich <brendan at>

> David Ungar raised this as a question from the audience after Tom's Proxies
> talk at DLS. One would expect no less from David, who indeed cited Self,
> which allows more intercession than harmony:proxies enables.
> This is not something I'm trying to get into harmony:proxies, but I thought
> it deserved more discussion, so here in es-discuss seems like a good place.
> One reason not to allow === to be trapped is mutation. If two object
> references are ===, then today we know they reference the same object. If
> that object is not frozen, then we expect to see effects through both
> references. If frozen, no effects can be committed or viewed via any
> reference.

Just to avoid confusion: by frozen, you mean deeply immutable here, right?
(since ES5-frozen objects can still be mutable, in which case the above
statement does not hold)

> If unfixed proxies could be === to unfrozen objects, then the proxy's
> handler could do whatever it wants and violate these old semantics.
> The value types idea, building on proxies, will want to support a value
> proxy that can intercede for === and most of the other operators. See
> (which is a tour de force that
> covers other applications than value types!).
> But value types, we think, would be frozen and compared by contents --
> property names and property values, recursively down the typically-shallow,
> frozen tree that represents the value. Details TBD, but this solves the
> mutation issue.
> So perhaps the answer to David's DLS question is twofold: "we chickened out
> for now; we're fixing for a subset of all objects later (maybe)".
> Still not the crisp and Self-ish answer one might hope for, but that is JS
> :for you :-/. So I went back to the Self well:
> 4.8 Equality, Identity, and Indistinguishability
> Equality, identity, and indistinguishability are three related concepts
> that are often confused. Two objects are equal if they “mean the same
> thing”. For example, 3 = 3.0 even though they are different objects and have
> different representations. Two objects are identical if and only if they are
> the same object. (Or, more precisely, two references are identical if they
> refer to the same object.) The primitive _Eq: tests if two objects are
> identical. Finally, two objects are indistinguishable if they have exactly
> the same behavior for every possible sequence of non-reflective messages.
> The binary operator “==” tests for indistinguishability. Identity implies
> indistinguishability which implies equality.
> It is actually not possible to guarantee that two different objects are
> indistinguishable, since reflection could be used to modify one of the
> objects to behave differently after the indistinguisability test was made.
> Thus, == is defined to mean identity by default. Mirrors, however, override
> this default behavior; (m1 == m2) if (m1 reflectee _Eq: m2 reflectee). This
> makes it appear that there is at most one mirror object for each object in
> the system. This illusion would break down, however, if one added mutable
> state to mirror objects.
> [From
> ]
> For JS, we don't have a clean equality analogue. One might be tempted to
> say that equality is ==, identity is === (ignoring -0 === 0 and NaN !==
> NaN), and indistinguishability is Object.eq (name still not settled on),
> from
> But JS == is not even an equivalence relation, and -0 is not identical to 0
> operationally even if one buys into the IEEE-754 standard and numerical
> programming precedents for NaN !== NaN.
> So it is more accurate to say JS has === for equality, it can have
> Object.eq for identity (self-hosted today on top of ===), and it *could*
> have indistinguishability.
> Should we consider indistinguishability on the Self model, with proxies
> instead of mirrors, and any other necessary changes?

I'm not sure I understand completely. Do we need 'indistinguishability' as a
third concept now that we have proxies that can appear to be other objects?
Let me clarify:

Assume p1 and p2 are two proxies that both proxy for an object o. Assume
also that these proxies want to appear to be indistinguishable from o (they
will faithfully behave like o for all meta-level operations). In that case I
can imagine it would be nice if there were a comparison operator that they
could trap to uphold the illusion of indistinguishability, both between p1
and p2 and between either p{1|2} and o.

As I see it, if Object.eq is introduced as the solid identity test that
cannot be fooled/intercepted, we could consider trapping '==='. Then p1 ===
p2 and p{1|2} === o could be made to return true. Object.eq will still
reveal their separate identities.

Btw, while browsing the Self programmer's manual, I also stumbled upon
section 4.1, which makes the observation that "Programs that depend on
object identity are also reflective". When viewed in this context, Object.eq
is a reflective operator, so it really should reveal proxies.


> JS will never be as simple as Self, but with proxies and value types based
> on them, it seems we might have get very close to the "right" answer to
> David's question.
> /be
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list