[Harmony Proxies] Proposal: Property fixing

Allen Wirfs-Brock allen at wirfs-brock.com
Thu May 12 18:48:50 PDT 2011

Thanks Tom,

As you point out, the are plenty of other implicit invariants that proxies don't enforce. For example:
   - a configurable property can be deleted
   - a [[Put]] to a non-writable data property does not change the value observable via [[Get]]
   - the attributes of a configurable property can be changed
   - obj.hasOwnProperty("foo")===obj.hasOwnProperty("foo")  //is true
   -Object.getOwnPropertyDescriptor(obj,"foo").hasOwnProperty("value) ) && obj.foo===obj.foo  //is true, ignoring NaN case
or lots of other consistency invariants among sequences of traps

I also wanted to point out that no modern browser fully respects the configurable invariants.  Every browser implements RegExp.prototype.compile and the de-facto standard  for its behavior blatantly  modifies the properties specified in 15.10.7  which are defined to be configurable false and writable: false.  The discussions that have occurred concerning  this method concluded that it (with that behavior) is essential to the web and that it should be included in the next ES edition.  I haven't figured out how we will reconcile this.  Probably by turning the affected properties into accessors.

On May 12, 2011, at 5:40 AM, Tom Van Cutsem wrote:

> ...

> Most of the enforced properties have to do with classification: instanceof, typeof and === are operators used to classify objects, and classifications typically come with some implied invariants (I'm aware of the fact that instanceof tests can be non-monotonic in JS).
> For {freeze|seal|preventExtensions}, one can make the case that defensive programming is one of their main use cases. Allowing proxies to gratuitously break them feels like taking away a lot of the usefulness of these primitives.

Generally, ES is not a hand holding language.  In particular, I don't see why these invariants are more important to enforce than some of those I mention above.  A buggy implementation can violate these invariants (and as I mentioned above, all browser implementations are to some degree buggy).  A buggy library can forget to freeze even though it is spec'ed do so.  I don't see why a buggy proxy is any more of a problem. 

My understanding was that a major motivation for these operations was  to create objects that can be passed to untrusted code while being safe from tampering.  The work around in the presences of proxies would seem to be don't pass any such buggy proxies or to create your own trusted proxy that wrappers the potentially buggy proxy.

> The use case is not always defensive programming, e.g. frozen objects facilitate caching without cache invalidation.

You can presumably still do that cache based upon the implied invariant. A failure to respect the invariant within the proxy is a bug that you might want to have a test case for but probably shouldn't cause you to change your design.   Just like most of the other  object invariants that proxies don't guarantee but your program probably depends upon.

> W.r.t. non-configurable properties: at this point I am convinced that Sean's API is better than the current design of outright rejecting non-configurable properties. Surely there will be cases where proxies will need to emulate non-configurable properties. Also, the fact that the default forwarding handler can't straightforwardly delegate getOwnPropertyDescriptor calls to its target (since it has to change the property's configurability) is a bad smell.

I don't like Sean's API because it requires the trapping infrastructure to build and perform validation against a potentially large data structure (per object table of all property names that have been set non-confgurable).   That's the sort of complex invariant maintenance that I don't think belongs at the implementation level of a dynamic language.  Consider as a use case the ES5 String object.  String objects have a "virtual" property foe each character of their underlying string value.  Each of these character properties is non-configurable but the String object itself is extensible.  A string value potentially has millions of such character properties and they routinely have thousands of them.  Using Proxies to implement this style of virtual properties over some fixed data source seems like a great use case. It should be possible and it should burden the underlying runtime with the overhead of validating a complex invariant that is practice would likely only fail during debugging of the Proxy.

> Building on an earlier idea proposed by David ("inheritance-safe proxies"), a compromise could be as follows:
> - allow proxies to emulate/intercept non-configurable properties without checking
> - introduce an "ESObject" abstraction such that if h is a user-defined proxy handler, ESObject(h) creates a "safe" proxy handler that checks conformance of the handler w.r.t. the above ES5 Object semantics. This can be useful for catching bugs, or preventing misbehavior, depending on your POV.

This seems like a reasonable approach.

I've come to view the "native object" semantics defined in ES5 section 8 as simply one of many possible object semantics that can be supported by the core ES language constructs.  Most of the ES built-in object types implement some sort of dialect of the "native object" semantics.  DOM objects have even greater divergence and arbitrary host objects in some implementation can diverge from "native object" semantics in even more ways.  I thing Proxies needed to be view as being closer in power to host objects then they are to "native objects".  Given this, it would be great to have a ESObject implementation that programmer can refine for the situations where they intend to make not or only minor variations form the standard semantics.

In terms to the core semantics of Proxies, I think we should restrict ourselves to the semantics that are required to support the individual statements and operators of the core ES language. These are the same semantics that are needed to make those statements and operators operate the current range of native, built-in, host objects.


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

More information about the es-discuss mailing list