Allen Wirfs-Brock (2013-07-30T16:57:04.000Z)
domenic at domenicdenicola.com (2013-08-04T22:53:03.957Z)
On Jul 30, 2013, at 1:25 AM, David Bruant wrote: > This apply to Date and the "time value", but I fail to see why this doesn't apply to every object and every property. For instance, every object is expected to have a [[Prototype]] object (at least in the ES5 era), which most likelty had a reserved slot in current implementations. Proxies challenge this, because they don't have a [[Prototype]], so the same sort of "memory safety hazard" apply for [[Prototype]]. > But I'm not too worry about that. I imagine implementors are well-aware of how deeply proxies are to integrate (retrofit!) in the object model. They'll figure it out for Date objects as well. It's important to be clear here that things Date's "time value" slot, the [[DateValue]] internal data property, are not actual "Properties". They represent private internal per instance state that is not accessible through any of the normal property access mechanisms. It is an unfortunate accident of history that we use the word "property" in talking about them. I've considered using replacing "internal data property" with another term. Maybe I should just go ahead and change over to calling "private data slots". So far in ES<=6 dealing with such private data slots is something that could be treated in a relatively ad hoc manner within the ES spec. and by implementations. But in ES7 we really want and need user definable per instance private data. The issues we are encountering here are a precursor of the issue we will see down the line and what we do now may constrain what we can do later. [[Prototype]] and other aspects of the basic ES object model are specified as part of the MOP (section 8.1.6.2) and mirrored by the Proxy handler interface. Every object whether ordinary, exotic, built-in, host-provided, etc. must expose the MOP interface to the implementation. Supporting that interface is what it means to be an ES object. "private data slots" are not part of the MOP, they represent an implementation specific side-channel. Strictly speaking, the MOP accesses the inheritance prototype chain via the [[GetInheritance]]/[[SetInheritance]] MOP operation. [[Prototype]] is just an internal data slot that ordinary objects use as backing store for those operations. Exotic objects do not necessary have a [[Prototype]] internal data slot. Proxy exotic objects and the currently spec. for Symbol exotic objects are examples of objects that don't need a [[Prototype]] internal data property. > Cases are annoyingly numerous, but finite. A test suite can go a long way. I heard the test suite is moving to Github :-) Only missing is an extensive doc of the test framework. Tests are normative and you can't write a valid test suite in the absence of an accurate specification. > This is not enough. > this-binding ("proxy.getMonth()" when the target is a Date) is only half of the story. The other half remains unadressed ("Date.prototype.getMonth.call(proxy)"). Exotic objects aren't always used as "this" value. This is exactly Tom's feedback actually. > We need the same solution for both cases (this and non-this usage of methods). I also raised this objection and it is what led to the recent update to the virtual object API referenced above. What that change does is make it easier for ES programmer to create proxies that behave in this manner. But, in the end we could not come up with a solution for the Date.prototype.getMonth.call(proxy) issue. The [[Invoke]] MOP operation/trap was added to minimize the actual occurrence of this scenario. You can't use 'call' to force a built-in to operate upon the wrong kind of object. > Let's let implementors deal with implementation issues. Let's just make sure the spec isn't impossible or too high barrier to implement. A test suite will do the rest. Let's care only for tests that make sense when authoring. > Implementors are free to dive in here to say I'm wrong and why. ES spec. largely exists to constrain how implementors deal with such issue in order to guarantee that different implementations have observably identical behavior. I think you are glossing over real issues that require real design thinking and which probably can't be addressed until ES7. With no offense to TomVC (who does the best job of any of our contributors in producing sound spec. material), I think the original Proxy strawman treatment of [[Class]] was gloss. I complete disagree WRT tests. Tests written without reference to some normative specification are just a reflection of how their developer thinks the system should work. > Is there a handler semantics with which it can fully work? That's all is needed. The ForwardingHandler semantics is close to what you want. But it still doesn't work the way you would like for direct "call" invocation or for things like Array.isArray. The base issue for either of these is that they don't indirect through the proxy handler and hence the handler doesn't have an opportunity to replace the proxy reference with the target reference. > The definition used in most spec algorithms is "has a this time value", so I guess this passes. Yes, it is sufficient for the spec algorithms which is a safety check that is only making sure that you don't apply a Date method to an object that doesn't have the required implementation level time value slot. But you are talking about the application layer . It is easy to say you want a way to "test if an object is a Date" or "is an Array". But what do you mean by those concepts at the application level. The ES spec. internally is able to make such tests, conforming to the internal invariants it needs to maintain. But those invariants aren't necessarily what you are asking for at the application level. At the root of this thread is the question of what does Array.isArray actually test and what are its application level use cases.. Array.isArray was a new method that was added in ES5. It wasn't added as a test to see if an object conformed to some Platonic Ideal of array-ness. It was specifically a reliable iframe-independent test for instances of the Array built-in constructor. I'm not really sure whether that is actually a very important use case, but that was the specific use case it was designed for. Do you have new use cases, that motivate the design of an enhanced Array.isArray? It would be quite easy to extend Array.isArray(obj) so that it delegated back to obj with a @@areYouAnArray method such as we are doing with @@isRegExp in certain places. However, if we do that you loose support for the original Array.isArray use case because any object could decide to return true from Array.isArray. > This thread feedback brings new data and it seems that the current handler offering isn't enough (and I understand can't be). yup