New private names proposal
brendan at mozilla.com
Tue Dec 21 17:32:12 PST 2010
On Dec 21, 2010, at 5:09 PM, Oliver Hunt wrote:
> On Dec 21, 2010, at 5:00 PM, Brendan Eich wrote:
>> On Dec 21, 2010, at 4:51 PM, Oliver Hunt wrote:
>>>> But what is an array index, then? uint32 is not a type in the language. Would proxy[3.14] really pass a double through?
>>> Yes, I would expect no coercion of any non-object. The reason for disallowing objects is safety afaik, those arguments don't apply to non-objects.
>>>> Array elements are named by a weird uint32 index name, with consequences on 'length' (but only up to 2^32 - 1 for length). I don't think passing the property name through uncoerced helps, unless you assume a normalizing layer above all name-based operations that specializes to index-names per Array's uint32 magic weirdness.
>>> And people are welcome to implement those semantics if they so desire.
>> If engines do not agree on whether 0xffffffff as a property name goes through a proxy get trap as a number and not a string, we have a problem.
>> Not all engines optimize 0xffffffff to the same (uint32) value; some keep it as a string since it doesn't fit in an int32.
> What does that have to do with anything? That's an internal implementation detail, not something that is directly observable from js (you can direct indirectly through timing, etc)
It matters to implementors what they might have to convert back to if the object is a proxy.
This started because you said "It would solve the problem of communicating private names to a proxy and allow efficient array-like implementations." Two issues:
1. Some people do *not* want to communicate private names to proxies. Others do, but there's no problem in principle, whether private names are a new typeof-type or just a built-in object [[Class]]. Your proposal here does nothing for the people who object, and doesn't really matter for those in favor of leaking private names via proxy handler trap name parameters.
2. "allow efficient array-like implementations" -- not really. Arrays must equate "42" and 42, and must update length for indexes in [0, 0xfffffffe] (closed range notation). Other properties must be string-equated. While it helps to get 42 instead of "42", it does not help to get 3.14 instead of "3.14" if you are implementing an array-like.
You want arbitrary values as identifiers to flow through to the proxy handler trap's name param without coercion. But many engines currently *do* coerce, and to internal types (not in-language) types.
So either implementations have to use a generic Value type for all property names above the per-[[Class]] implementation layer, and coerce only under that layer; or else keep their optimized above-the-[[Class]]-layer property-name type encodings (using internal types, etc.) and undo the coercion in the Proxy (object and function proxy) implementations, to implement what you want.
I don't believe all implementations will re-layer to let values pass through uncoerced. This leaves undoing the coercion in proxy trap-calling code, which is not only more expensive for "3.14" -> 3.14, it is ambiguous: the original type was lost due to coercion, so you're really talking about requiring all engines to layer things so property names are never coerced (apart from string intern'ing).
I don't see that flying with all implementors, and I don't see it buying array-like proxies much. It still looks like overspecification.
To let private names through, we need only enlarge the type of names in ECMA-262 from string to (string | private name) as the proposal says. To let array indexes through, we might do something similar, but it would not let 3.14 through as a double.
More information about the es-discuss