[[Extensible]]and Proxies (Was: Proxy.isProxy )

Mark S. Miller erights at google.com
Thu Jul 14 16:59:36 PDT 2011

On Thu, Jul 14, 2011 at 3:00 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

> On Jul 14, 2011, at 1:19 PM, Mark S. Miller wrote:

> Absent other costs, that's a fine thing to want. But because of those
> costs, it was never a goal of the proxies design.
> I think several of us have been quite consistent in expressing that we are
> looking for a mechanism for implementing in pure ES things that currently
> require host objects or enhanced object semantics of the sort that
> historically has been defined for built-ins such as Array objects. If that
> was not one of the goals for Proxies I misunderstood.  Perhaps Proxy is not
> what we need then.

I'm sorry you misunderstood. I recall you were at Dynamic Languages 2010,
where you gave a great keynote and Tom presented our paper on proxies
We have publicized that paper on es-discuss and to the committee and linked
to it from the proxies wiki pages. We have hardly kept it a secret. It says:

>From section section 4.4 "Temporary Intercession"

Recall from section 3.2 that ECMAScript 5 enables the creation of
> tamper-proof objects. A tamper-proof object provide useful guarantees that
> programmers can rely upon. When designing a proxy API, care should be
> taken that proxies cannot break these guarantees. For example, if o is an
> object, then Object.freeze(o) freezes that object. If the programmer knows
> o is frozen, he can rely on the fact that the number of properties
> contained in o will no longer change. If o is a proxy, we do not want a
> proxy to violate such assumptions.
> [...]
> if an operation imposes strong consistency requirements on a proxy object
> (such as becoming immutable), intercession should be disabled for some
> or all of the operations intercepted by proxies.

And essentially *all* of section 4.6 "Selective Interception".

>> Historically there never were any real restriction on what such objects
>> can do.
>  The DOM and RegExp.prototype.compile demonstrate this.  The host object
>> object restrictions added in ES5 don't apply to built-in objects
> Allen, you and I have been over this, both on list and off. This is simply
> not true. All the restrictions at the end of 8.6.2 are stated as applying
> only to host (i.e., non-native) objects only because we did not need to
> state that they apply to native objects. E5.1 specifies the behavior of
> native objects in enough detail that we can read the spec and verify that
> they must obey these constraints as well.
> Implementations are free to add new built-in objects (see 4.3.28).  Without
> any stated requirements for such objects you have no guarantees.

Quoting that section in full:

> **built-in method
> *method that is a built-in function
> NOTE Standard built-in methods are defined in this specification, and an
> ECMAScript implementation may specify
> and provide other additional built-in methods.

My interpretation of this is simply that implementations can provide new
built-in methods that are still constrained to operate as native functions
if they are to be considered native functions. As with the specified
built-in native functions, they can have [[Call]] and [[Construct]] methods
that are not written in JavaScript. I don't understand what else you are
reading into this, unless it's captured by the peek and poke discussion

> Further more, in writing specification material such as the alternative
> internal methods, I was never aware of any requirements that had to be meet
> by those implementations other than whatever was necessary to describe the
> legacy or new semantics that we were trying to specify.  As far as I know,
> there is no comprehensive normative specification of invariant that must be
> maintained by all objects.

That is why I was and continue to agree with you that we should seek to
arrive at agreement on such a clear normative specification.

>  For example, the ES5 spec says "Host object may implement these internal
>> methods in any manner unless otherwise specified"  and "The
>> [[DefineOwnProperty]] internal method of a host object must not permit the
>> addtion of a new property...if the [[Extensible]]...has been observed...to
>> be false".  So, in that case [[DefineOwnProperty]] can't add a new property
>> but [[Delete]], or [[Get]], or [[DefaultValue]] or any other the internal
>> methods could as nothing specifies that they can't.
> I agree that this is a spec bug. We should fix this in the ES5 errata.
> No it is not a bug.  There was never any consensus on a larger set of
> invariants or even as far as I can recall a proposal for such.  I don't know
> whether or not we would have or in the future can achieve consensus on that.
>  For now, ES5.1 is what it is and and unless something is clearly internally
> inconsistent, unintended breakage from an earlier edition, or breaks long
> establish browser behaviors I don't think you can call it a bug.

Do you really think it makes sense to allow new properties to appear on
non-extensible objects? Really?

Perhaps you do. Again, unless and until we get agreement to clean up these
(irregularities, inconsistencies, features, whatever you want to call them)
in 8.6.2, ES5.1 is, as you say, what it is. I hope we can do better.

>>  Finally,  in adding the restrictions to ES5 I don't think there was any
>> serious effort to see whether or not the restrictions were consistent with
>> what host objects actually did.  Certainly they are not consistent with the
>> commonly implemented behavior of RegExp.prototype.compile.
> Ok, I admit I haven't paid as much attention to RegExp.prototype.compile as
> I should, because, thankfully, it is deletable on all major browsers. Where
> can I read about its cross-browser de-facto behavior?
> https://bugzilla.mozilla.org/show_bug.cgi?id=630284
> The Microsoft implementation is described in
> http://msdn.microsoft.com/en-us/library/ff955265(v=VS.85).aspx but to be
> sure what it means you need to write some tests.
> These was off-list email earlier among various implementors about this
> issue.  this is what Luke said at the time: [...]

Thanks. Most useful. I will look at these and respond once I have.

>> My sense is that Mark has some specific invariants that he wishes were
>> guaranteed in ES implementations and he wants to make it impossible to
>> violate those invariants using Proxies
> y
>> even though there is no such invariants imposed on built-in objects
> wrong, as we've discussed numerous times.
> So we disagree WRT whether the specified behavior of features in current
> specification can be extrapolated as imposing limitation on future unrelated
> features and specifications.

I agree that this is a good summary of our disagreement, yes.

> and the host object invariants are incomplete and hard to make impossible
>> to violated.
> Host objects are part of the platform. A platform provider is free to
> violate any part of the spec they like, and there's nothing we can do about
> it other than to add tests to std test suites to make the violations obvious
> to the community.
> We could provide a defined interface mechanism that validates constraints
> or limits behavior in a way that guarantees the desired invariants. That's
> what Proxies appear to be trying to do, why not do it for host objects.  If
> you can depend upon host objects actually supporting your invariants why
> does not matter whether or not Proxy objects also do so.

I think this is key to the whole discussion, as you and I have discussed
verbally. The main use case you seem to be thinking in terms of is Mozilla's
own use, as a platform provider, of the proxy mechanism as a way to replace
your current mechanisms for providing host objects. This is a laudable goal
which I fully support. However, for your use as a platform provider, it is
legitimate for you to provide yourself dangerous shortcuts that we cannot
expose to untrusted code, given that you take responsibility for not abusing
these dangerous shortcuts.

For clarity, let's take an extreme example: peek and poke. For those who
missed the history, peek and poke <
http://en.wikipedia.org/wiki/PEEK_and_POKE> were primitives in some Basics
for providing direct unchecked access to raw memory. If you, as platform
providers, wanted to provide yourself with peek and poke operations in order
to gain some efficiency or whatever, there's nothing fundamentally wrong
with that. But clearly, no matter what the gains, that shortcut should never
be exposed to untrusted code.

This also demonstrates out why the notorious Chapter 16 exemptions need to
be tightened. As currently written, a platform could provide peek and poke
as native methods without violating the spec. However, so far I am at a loss
on how to tighten this up so that it is neither too tight for agreement nor
too loose for safety. Perhaps this is the real 4.3.28 issue you were raising

>> If we really want to do this, then we need to really define a complete and
>> self consistent set of invariants that we are willing to apply to all
>> objects (include built-ins and host) now and into the future.  [...]
> Yes. For a start,
> * That the statechart at [<
> http://wiki.ecmascript.org/doku.php?id=es3.1:attribute_states>] represents
> all the states and transition possible for a property.
> * 8.6.2, with the clarification that it applies to both native and
> non-native, and with the [[Extensible]] spec bug that you point out fixed.
> The normative specification of valid state transitions is actually 8.12.9,
> but that only applied to objects that use that definition of
> [[DefineOwnProperty]].  Any extrapolation to other situations hasn't been
> normatively adopted.
> * The "eternal invariants" from <
> https://mail.mozilla.org/pipermail/es-discuss/2011-May/014150.html>.
> We can certainly discuss these, but TC39 hasn't adopted them.

Understood. Those three bullets are my answer to your inquiry about what
"complete and self consistent set of invariants" I'd like to see us agree on
going forward. I believe they are better than our current ES5.1 baseline. If
you agree, perhaps we can make some progress.

>> Personally, I'm skeptical that we can agree upon such a set of invariants
>> that are compatible with the legacy language and DOM. I'm also an skeptical
>> of the need to do so for Proxies or for built-in and host objects. But, if
>> we want to go for it, then we should proceed and try to define the universal
>> object invariants and see if we can reach consensus on accepting them.  If
>> we can't, then we shouldn't be restricting Proxy semantics based upon some
>> assumed invariants.
> Until and unless we can all agree on something else, we stick with what we
> have already agreed to. With our current agreement as a baseline, I am
> confident we can agree on something better -- like cleaning up the
> [[Extensible]] spec bug you point out above.
> And what we have already agreed to is only what is currently in the ES5.1
> spec, as written.  As I expressed above, I don't think there is agreement
> about extrapolations of the text to situations that aren't explicitly called
> out in the specification.
> Sorry, if that seems unharmonious but it seems like the only solid footing
> we have.

Yup. It seems we no longer have agreement on how to extrapolate to our
current standards activities. That is disappointing, and seems to leave us
stuck. Let us try to figure out how to go forward from here. I am quite
anxious to get back to our harmonious state of progress towards a better
JavaScript. This one issue aside, I've very encouraged about how well all of
this has been proceeding!

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110714/974ddd12/attachment-0001.html>

More information about the es-discuss mailing list