Re: Read access to [[Class]]?
Is the window.opera object in fact a host object? From the documentation at http://www.howtocreate.co.uk/operaStuff/operaObject.html, it seems the only magic behavior is in its methods, not in the object itself. Is there something magical about the behavior of this object itself? Note that just because the object itself is non-standard and provided by the host does not make it a host object. On Sat, Jan 28, 2012 at 1:15 AM, John-David Dalton john.david.dal...@gmail.com wrote: I noticed in the ES6 draft it states that host objects *do not* have the [[NativeBrand]] internal property. I think do not have should be reworded to are not required to have. This would allow existing inferences like `{}.toString.call(window.opera) == '[object Opera]'`. - JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
On Jan 27, 2012, at 10:15 PM, John-David Dalton wrote: I noticed in the ES6 draft it states that host objects *do not* have the [[NativeBrand]] internal property. I think do not have should be reworded to are not required to have. This would allow existing inferences like `{}.toString.call(window.opera) == '[object Opera]'`. I probably need to be more explicit about host objects and add another step just before step 5 If O is a host object, let tag be an implementation defined string value. The value may not be Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, and String. Also, the definition of Host Object needs to be tighten up to make it clear that an object is only a host object if it has some magical behavior. Finally, window.opera is really just a normal object it could use my proposed private name based mechanism to set its toString tag. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
On Jan 28, 2012, at 8:21 AM, Allen Wirfs-Brock wrote: On Jan 27, 2012, at 10:15 PM, John-David Dalton wrote: I noticed in the ES6 draft it states that host objects *do not* have the [[NativeBrand]] internal property. I think do not have should be reworded to are not required to have. This would allow existing inferences like `{}.toString.call(window.opera) == '[object Opera]'`. I probably need to be more explicit about host objects and add another step just before step 5 If O is a host object, let tag be an implementation defined string value. The value may not be Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, and String. Also, the definition of Host Object needs to be tighten up to make it clear that an object is only a host object if it has some magical behavior. Yes, it's an old subtle terminological topic which is required to be mentioned in the spec, I think it would be good. In fact, if an object is completely conforming with the spec, it cannot be distinguished from native objects -- regardless in which language it's written (in JS itself or in a lower language). Moreover, many host objects are implemented in JS itself -- e.g. some standard libraries as in Node.js. I called them inefficiently as native-host objects. But from this viewpoint -- is this algorithm step is correct? I.e. window.opera being as a native-host can nevertheless have as its [[NativeBrand]] values of Array, Object, etc? And a host object then becomes as an object provided by a host environment and has semantic differentiations from this specification. (the only thing it's needed to consider is not to make it even more confused or complicated). Dmitry Finally, window.opera is really just a normal object it could use my proposed private name based mechanism to set its toString tag. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
@MarkM Is there something magical about the behavior of this object itself? For kicks the magical bit would be its awesome pre ES6 internal [[Class]] value. Can we leave magical out of a spec convo? Note that just because the object itself is non-standard and provided by the host does not make it a host object. http://es5.github.com/#x4.3.8 A host object is an object supplied by the host environment to complete the execution environment of ECMAScript. Seems like the `opera` object falls into that description. I mean it could be a built-in if supplied by the ECMAScript environment but that's beside the point. I really just want the wiggle room that ES5.x provides for [[Class]]/flags/tags/brands. -JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
@Allen I probably need to be more explicit about host objects and add another step just before step 5 If O is a host object, let tag be an implementation defined string value. The value may not be Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, and String. +1 for less complex solution and a continuation of the pre-ES6 wording. Also, the definition of Host Object needs to be tighten up to make it clear that an object is only a host object if it has some magical behavior. -1 magical. Finally, window.opera is really just a normal object it could use my proposed private name based mechanism to set its toString tag. -1 for the more complex option. -JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
The current ES6 draft defines its like this: 15.2.4.2 Object.prototype.toString ( ) When the toString method is called, the following steps are taken: If the this value is undefined, return [object Undefined]. If the this value is null, return [object Null]. Let O be the result of calling ToObject passing the this value as the argument. If O has a [[NativeBrand]] internal property, let tag be the corresponding value from the Table 23. Else, let tag be the string value Object. Return the String value that is the result of concatenating the three Strings [object , tag, and ]. Table 23 — Tags for Classified Native Objects [[NativeBrand]] Value tag Value NativeFunction Function NativeArray Array StringWrapper String BooleanWrapper Boolean NumberWrapper Number NativeMath Math NativeDate Date NativeRegExp RegExp NativeError Error NativeJSON JSON NativeArguments Arguments Not sure that it makes sense (backward compatibility...), but one could handle primitive booleans, numbers, and strings differently: Currently: $ Object.prototype.toString.call(true) '[object Boolean]' Alternative: $ Object.prototype.toString.call(true) '[primitive boolean]' -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
On Jan 28, 2012, at 11:33 AM, John-David Dalton wrote: @Allen Also, the definition of Host Object needs to be tighten up to make it clear that an object is only a host object if it has some magical behavior. -1 magical. the spec. won't actually say magical, but the important distinction that the spec. needs to make concerns objects that have special behaviors (ie, different from the native object behaviors defined within the specification). It really doesn't matter to the spec if such objects are supplied by the engine implementation or a host environment or some foreign object interface. The only thing that is important is that they in some way deviate from the definition of native objects. Similar, if an object is not observably different in its behavior from the specification for a native object then it does not matter how it was defined. In the case of ({}}.toString.call(window.opera) the fact that it returns a value that is not in the specification is enough magic to qualify window.opera as such a non-native object. Finally, window.opera is really just a normal object it could use my proposed private name based mechanism to set its toString tag. -1 for the more complex option. We want to be able to define things that were historically implemented as host objects using pure ECMAScript code. One things such objects have done is to extend the range of values produced by Object.prototype.toString. So, we need a pure ECMAScript way to accomplish that. Allen Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
@Allen We want to be able to define things that were historically implemented as host objects using pure ECMAScript code. One things such objects have done is to extend the range of values produced by Object.prototype.toString. So, we need a pure ECMAScript way to accomplish that. You could simplify it by making `NativeArray = Array` and `NativeRegExp = RegExp` and so on. Then you could drop the Tags table and extending the range of Object#toString is as easy as adding a custom [[NativeBrand]] property value. - JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
Axel Rauschmayer wrote: Alternative: $ Object.prototype.toString.call(true) '[primitive boolean]' No gratuitous runtime incompatibility, it will only break compat and punish early browser impelmentations. We've been over this. Please resist the urge to clean things up. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
On Jan 28, 2012, at 4:07 PM, John-David Dalton wrote: @Allen We want to be able to define things that were historically implemented as host objects using pure ECMAScript code. One things such objects have done is to extend the range of values produced by Object.prototype.toString. So, we need a pure ECMAScript way to accomplish that. You could simplify it by making `NativeArray = Array` and `NativeRegExp = RegExp` and so on. Then you could drop the Tags table and extending the range of Object#toString is as easy as adding a custom [[NativeBrand]] property value. and name the internal property [[Class]]. But then, how would you implement it in pure ES code? Also noite that [[Class]] doesn't actually exist as string valued per object state in many implementations. That is one of the problems with the current spec, it creates the impression that it such state actually exists. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
@Allen and name the internal property [[Class]]. But then, how would you implement it in pure ES code? You can name the internal property whatever you want [[Class]] / [[NativeBrand]] / [[Whatevz]]. It's internal so less important to me what the name is. I don't think setting [[NativeBrand]] or having a mechanism for returning custom Object#toString values should be allowed outside of the ES implementation internals (ignoring overwriting the method with a dev defined method). This is one of the reasons why `{}.toString.call(window.opera)` is such a strong inference because it's harder to fake w/o mucking with the Object.prototype. Also note that [[Class]] doesn't actually exist as string valued per object state in many implementations. That is one of the problems with the current spec, it creates the impression that it such state actually exists. Sounds like a per implementation issue/detail. I'm sure there are lots of internal corners cut in every implementation. -JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
John-David Dalton wrote: Also note that [[Class]] doesn't actually exist as string valued per object state in many implementations. That is one of the problems with the current spec, it creates the impression that it such state actually exists. Sounds like a per implementation issue/detail. I'm sure there are lots of internal corners cut in every implementation. No, we do not want normative spec language requiring a per-object private-named property that determines the Object.prototype.toString.call(x).slice(8,-1) result. Doing this naively will both impose unacceptable overhead *and* allow type-confusion attacks. I sympathize with your goal of avoiding two cases, native and host, one of which enumerates cases, the other underspecified -- with the private-name override applying only to the non-enumerated cases. We should try to unify machinery where we can. Not at the price of per-instance class-name. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
@/be No, we do not want normative spec language requiring a per-object private-named property that determines the Object.prototype.toString.call(x).slice(8,-1) result. Doing this naively will both impose unacceptable overhead *and* allow type-confusion attacks. I'm talking about adding back the wording that ES5.x currently has allowing host objects to set their own internal [[Class]] (or whatever it's new incarnation is) value. Most objects will still have an internal [[NativeBrand]] property of some kind associated with them so I don't see how this is an overhead concern. Not at the price of per-instance class-name. The current ES6 draft handles this by allowing objects to *not* have a [[NativeBrand]] property specified as `Object#toString` will simply return [object Object]. - JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
On Sat, Jan 28, 2012 at 7:11 PM, Brendan Eich bren...@mozilla.org wrote: Axel Rauschmayer wrote: Alternative: $ Object.prototype.toString.**call(true) '[primitive boolean]' No gratuitous runtime incompatibility, it will only break compat and punish early browser impelmentations. We've been over this. +1. Please resist the urge to clean things up. Hi Brendan, I think I agree with what I think you're trying to say. But I do not agree with what you said. In going from ES3 to ES5, we've cleaned up many things. In going from ES5 to ES6, we are again striving to clean up some things, such as completion reform. But for every thing we successfully clean up, there may be 1000 we would have liked to clean up but can't. Such cleanups are the riskiest part of what we do; and we have learned, IMO, the appropriate level of conservatism. Sometimes we overshoot and sometimes we undershoot. But when we succeed, it is some of our most important accomplishments. I hope we never lose this urge. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
John-David Dalton wrote: Doing this naively will both impose unacceptable overhead*and* allow type-confusion attacks. I'm talking about adding back the wording that ES5.x currently has allowing host objects to set their own internal [[Class]] (or whatever it's new incarnation is) value. Most objects will still have an internal [[NativeBrand]] property of some kind associated with them so I don't see how this is an overhead concern. It's not a problem if [[NativeBrand]] cannot be shadowed or own- vs. in-tested. Then it's just like [[Class]], only narrower. Not at the price of per-instance class-name. The current ES6 draft handles this by allowing objects to*not* have a [[NativeBrand]] property This too may be ok if not observable. But you wrote: You could simplify it by making `NativeArray = Array` and `NativeRegExp = RegExp` and so on. Then you could drop the Tags table and extending the range of Object#toString is as easy as adding a custom [[NativeBrand]] property value. and Allen then replied: But then, how would you implement it in pure ES code? That's desirable for a self-hosted DOM, but the use of a private name means that we have two cases: private name not in the object, so use an internal class test equivalent in observable outcome via O.p.toString to ES1-5; private name in the object, use its value (ToString'ed). I don't see how to simplify further without using the private name for both cases, in which case we have overhead (less for in than own, we could bind the private name in the appropriate prototype object) and, more significant: the type-confusion problem due to shadowing. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
Hi Mark, When I wrote: Please resist the urge to clean things up. I did not mean resist at all costs. Just resist the low-reward/high-compat-break-risk temptations. HTH, /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
@/be This too may be ok if not observable. But you wrote: You could simplify it by making `NativeArray = Array` and `NativeRegExp = RegExp` and so on. Then you could drop the Tags table and extending the range of Object#toString is as easy as adding a custom [[NativeBrand]] property value. and Allen then replied: But then, how would you implement it in pure ES code? Sorry for the confusion. I wasn't suggesting exposing this stuff. I think the [[NativeBrand]] property should be internal. -JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
@MarkM A host object is an object supplied by the host environment to complete the execution environment of ECMAScript. Sigh. This came up last time as well, and as participants in the spec writing process our only excuse was That text isn't normative. That doesn't really excuse it from being so wrong that it leads people into endless confusion. If ES6 does keep the current terminology, we must at least fix or remove this confusing text. JavaScript was my first language so I don't have the pollution of Java-isms to confuse me. I can only go by what's spec'ed as I lack the inside info ;) Native object: http://es5.github.com/#x4.3.6 Built-in object: http://es5.github.com/#x4.3.7 Host object: http://es5.github.com/#x4.3.8 I should stress that the technical category of the object is less important to me. I really just wanted to +1 allowing objects like `window.opera` to continue to have `{}.toString.call(...)` results like `[object Opera]` under ES6. - JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
[[Class]] begone in ES6. Also you are making an ambiguous API. If we add class syntax and someone writes class string {}, which string is string? The class trope should not be mixed with type, IMHO. /be Axel Rauschmayer mailto:a...@rauschma.de January 27, 2012 4:27 AM I would still love to get read access to the [[Class]] property in ES.next. Proposal: A function getTypeName(). - Primitives p: return typeof p (except: null for null) - Objects o (including functions): return o.[[Class]] Axel -- Dr. Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de home: rauschma.de http://rauschma.de twitter: twitter.com/rauschma http://twitter.com/rauschma blog: 2ality.com http://2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
On Fri, Jan 27, 2012 at 12:08 PM, Brendan Eich bren...@mozilla.org wrote: [[Class]] begone in ES6. Assuming the public facing API has no intention of breaking back compatibility, what internal property will be read to determine the return value of Object.prototype.toString (15.2.4.2)? Also you are making an ambiguous API. If we add class syntax and someone writes class string {}, which string is string? The class trope should not be mixed with type, IMHO. /be Axel Rauschmayer mailto:a...@rauschma.de January 27, 2012 4:27 AM I would still love to get read access to the [[Class]] property in ES.next. Proposal: A function getTypeName(). - Primitives p: return typeof p (except: null for null) - Objects o (including functions): return o.[[Class]] Axel -- Dr. Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de home: rauschma.de http://rauschma.de twitter: twitter.com/rauschma http://twitter.com/rauschma blog: 2ality.com http://2ality.com __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
Rick Waldron wrote: On Fri, Jan 27, 2012 at 12:08 PM, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: [[Class]] begone in ES6. Assuming the public facing API has no intention of breaking back compatibility, what internal property will be read to determine the return value of Object.prototype.toString (15.2.4.2)? [[NativeBrand]] if my memory does not fail me; but it only works for builtins, other will all return [[object object]]. Look at the newest proposal, allenwb has posted a link a week or two ago (I can't find it, I probably deleted the mail with it already). Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
On Jan 27, 2012, at 9:59 AM, Rick Waldron wrote: On Fri, Jan 27, 2012 at 12:08 PM, Brendan Eich bren...@mozilla.org wrote: [[Class]] begone in ES6. Assuming the public facing API has no intention of breaking back compatibility, what internal property will be read to determine the return value of Object.prototype.toString (15.2.4.2)? The current ES6 draft defines its like this: 15.2.4.2Object.prototype.toString ( ) When the toString method is called, the following steps are taken: If the this value is undefined, return [object Undefined]. If the this value is null, return [object Null]. Let O be the result of calling ToObject passing the this value as the argument. If O has a [[NativeBrand]] internal property, let tag be the corresponding value from the Table 23. Else, let tag be the string value Object. Return the String value that is the result of concatenating the three Strings [object , tag, and ]. Table 23 — Tags for Classified Native Objects [[NativeBrand]] Value tag Value NativeFunction Function NativeArray Array StringWrapper String BooleanWrapper Boolean NumberWrapper Number NativeMath Math NativeDate Date NativeRegExp RegExp NativeError Error NativeJSON JSON NativeArguments Arguments Basically, there is a fixed set of hardwired (to the spec.) object kinds that toString knows about. There is no implication that all objects must carry around an additional string value that is used to parameterize toString. If you want to extend an implementation with new built-in object kinds that toString recognizes then you must also extend your implementation of toString. [[Class]] has been treated by some as a mandatory implementation level extension point for adding new internal types, but it wasn't. Note that I have considered extending the above definition of toString with an explicit ES level extension point based using private names: If O has as well known private name property (think of it as: privateToStringTag) then tag is set to ToString of the value of that property. This would happen between steps 4 and 5. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
Thanks to both of you, I wasn't aware that this was already documented in an ES6 draft - my apologies. Rick On Fri, Jan 27, 2012 at 1:23 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Jan 27, 2012, at 9:59 AM, Rick Waldron wrote: On Fri, Jan 27, 2012 at 12:08 PM, Brendan Eich bren...@mozilla.orgwrote: [[Class]] begone in ES6. Assuming the public facing API has no intention of breaking back compatibility, what internal property will be read to determine the return value of Object.prototype.toString (15.2.4.2)? The current ES6 draft defines its like this: *15.2.4.2 Object.prototype.toString ( )* When the *toString* method is called, the following steps are taken: 1. If the *this* value is *undefined*, return *[object Undefined]*. 2. If the *this* value is *null*, return *[object Null]*. 3. Let *O *be the result of calling ToObject passing the *this *value as the argument. 4. If *O* has a [[NativeBrand]] internal property, let *tag* be the corresponding value from the Table 23. 5. Else, let *tag* be the string value *Object*. 6. Return the String value that is the result of concatenating the three Strings *[object *, *tag*, and *]*. *Table 23 — Tags for Classified Native Objects* *[[NativeBrand]] Value* *tag Value* NativeFunction *Function* NativeArray *Array* StringWrapper *String* BooleanWrapper *Boolean* NumberWrapper *Number* NativeMath *Math* NativeDate *Date* NativeRegExp *RegExp* NativeError *Error* NativeJSON *JSON* NativeArguments *Arguments* Basically, there is a fixed set of hardwired (to the spec.) object kinds that toString knows about. There is no implication that all objects must carry around an additional string value that is used to parameterize toString. If you want to extend an implementation with new built-in object kinds that toString recognizes then you must also extend your implementation of toString. [[Class]] has been treated by some as a mandatory implementation level extension point for adding new internal types, but it wasn't. Note that I have considered extending the above definition of toString with an explicit ES level extension point based using private names: If *O* has as well known private name property (think of it as: privateToStringTag) then *tag* is set to ToString of the value of that property. This would happen between steps 4 and 5. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Read access to [[Class]]?
I noticed in the ES6 draft it states that host objects *do not* have the [[NativeBrand]] internal property. I think do not have should be reworded to are not required to have. This would allow existing inferences like `{}.toString.call(window.opera) == '[object Opera]'`. - JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss