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.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss