[Harmony Proxies] Proposal: Property fixing

Allen Wirfs-Brock allen at wirfs-brock.com
Tue May 10 23:41:38 PDT 2011

On May 10, 2011, at 11:18 AM, Sean Eagan wrote:

> On Mon, May 9, 2011 at 10:38 AM, Tom Van Cutsem <tomvc.be at gmail.com> wrote:
>>>> I do see benefit in this proposal as an aid for proxy writers to develop
>>>> more well-behaved proxies. But for that purpose it seems that this
>>>> proposal
>>>> can be fully written as a Javascript library layered on top of the
>>>> existing
>>>> API.
>>> But couldn't the same be said of the "fix" trap, frozen prototype, and
>>> frozen typeof for proxies ?
>> As for the fix trap: there needs to be some way for a proxy to react to
>> freeze|seal|preventExtensions, even with your proposed extension.
>> As for frozen typeof: there have been proposals in the past of adding an
>> additional argument to Proxy.create to configure the proxy's |typeof| value
>> (still operating under the restrictions of ES5 11.4.3). If this
>> configurability turns out to be necessary in certain scenarios, I'm sure it
>> will be reconsidered.
>> As for frozen prototype: despite non-standard __proto__, the current
>> consensus is to move away from mutable prototypes, not to add standardized
>> features to support it.
> I was not implying that these invariants should not be enforced, but
> rather that if they are enforced, then non-configurable properties
> should be enforced as well, as not doing so seems arbitrary and thus
> confusing to users of the API.  As Allen mentioned, there are other
> important invariants that are not currently enforced, and I would make
> the same argument there, that either they should be enforced as well,
> or that nothing should be enforced.

I think we are dancing around one of the key differences between static languages and dynamic languages.  Static languages make guarantees about a set of potentially complex invariants  (for example, subtype conformance).   They can do this because the necessary work to detect violations of those invariants is performed ahead of time before the program is allowed to execute.  Dynamic languages do most invariant validation as the program runs and hence generally restrict themselves to guaranteeing simple invariants (for example, memory safety) that can be cheaply performed many times as the program runs.  Dynamic languages generally avoid expense checking of complex invariants and instead assume that any critical violation of complex invariants will ultimately manifest  themselves as violations of the simple invariants that are checked.

A related difference is that a static language generally rejects programs when it proves the set of all possible program inputs produces some states that violate the language's invariants.  The program is rejected, even if the input states that produce the invariant violations will never occur in practice.  This is a conservative (or pessimistic) approach -- if a program might fail, we assume it will fail.  Dynamic languages generally only reject programs (at runtime) when the actual data values used by the program violates the language's invariants.  This is a permissive (or optimistic) approach -- if a program might work, we give it the benefit of the doubt and let it run up to the point it begins to misbehave. 

The configurability restrictions on Proxies seems to be trying to apply a static language perspective to the very dynamic ES language.  They are based upon a complex invariant (what can/cannot be assumed after  observing the state of a configurable attribute).  Because, there is at best difficult to guarantee that user written proxy handlers will correctly enforce the invariants associated with of configurable:false it is forbidden for a proxy to set configurable to that state.  It is pessimistic, it says that because somebody might write a buggy proxy setting configurable we won't let them write any proxy that sets configurable.  An alternative that has been proposed is to try to dynamically enforce the configurable invariants.  But that is an example, of moving expensive (and probably highly redundant)  complex invariants checks into runtime.  While it would catch buggy programs, but has the potential of imposing a significant runtime performance penalty on valid programs. The normal dynamic language approach to this sort of problem is to be optimistic about the validity of the program while continuing to guarantee memory safety, and depending upon conventional testing procedure to detect more complex error conditions.


More information about the es-discuss mailing list