[+es5-discuss as a possible errata issue arises below]

On Sat, Jul 17, 2010 at 12:37 AM, Garrett Smith <dhtmlkitc...@gmail.com>wrote:

> On 7/16/10, Mark S. Miller <erig...@google.com> wrote:
> > On Fri, Jul 16, 2010 at 9:54 PM, Garrett Smith
> > <dhtmlkitc...@gmail.com>wrote:
> >
> >> I have a question reqarding [[Class]] property as defined In ES5:
> >>
> >> | The value of the [[Class]] internal property of a host object
> >> | may be any String value except one of "Arguments", "Array",
> >> | "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number",
> >> | "Object", "RegExp", and "String"
> >>
> >> May it be something other than a string value? Or must it be a string
> >> value?
> >>
> >
> > It must be a string value.
> >
>
> The specification says "may".
>

Ah. I see the ambiguity. "may" there is modifying "any". It should probably
have been stated:

    ...must be a String value and may be any String value except...

In reviewing the document, the possibility that text would allow non-String
[[Class]]es had not occurred to me. Now that you point it out, and can see
some reasons why we might want to leave the current text alone and allow
non-String [[Class]]es.



>
> >
> >>
> >> Why must a host object's class be none of the built-in classes listed?
> >>
> >
> > So that the [[Class]] property serve as a reliable nominal type check for
> > the contract that the other internal properties and methods satisfy. This
> is
> > used primarily within the spec itself. Previously, it wasn't clear what
> was
> > meant when the spec said, for example, "if F is a function". Now we
> clearly
> > say "if the [[Class]] of F is 'Function' " if that's what we mean.
> >
>
> I think I see the problem.
>
> What you really want to say there is:
>
> |  The value of the [[Class]] internal property of any non-native host
> |  object must be any String value except one of...
>

Saying "non-native" and "host" together is redundant. Although the language
of 4.3.6 and 4.3.8 is not as clear as it should be, I read these as stating
that all EcmaScript objects are either host or native. No object can be both
host and native. And no object can be neither host nor native.



>
> Because that allows `alert` to be any native ECMAScript object
> (Function, Object, etc), while still letting it be defined as a host
> object and not violating that spec.



"that spec"? What specification demands that alert be a host object? I have
not heard of any. This might be a consequence of the upcoming WebIDL-to-ES5
language bindings, but I have seen no draft and so have no idea. My own
preference would be for these language bindings to result in alert being a
native Function, but that's an argument for a different standards committee
;).

If an implementation's alert is a Function, then it is a native object and
its [[Class]] must be "Function". It can still be an object provided by a
host environment whose [[Call]] behavior is written in C++. This simply
makes it a host provided native built-in object (4.3.7), not a host object.




> Iff, however, following my
> proposed amendment, `alert` had [[Class]] "Object", and it was not a
> native ES object (as in IE versions), then it would be a specification
> violation.
>
> > But it is also used from JS. Host objects are exempt from most of the
> > specific behaviors specified for specific kinds of native objects. Were a
> > host object to be able to allege to be a kind of native object without
> > behaving as that kind of native object behaves, that would be bad.
> >
>
> This is not in the spec:
> "without behaving as that kind of native object behaves"
>

See 4.3.6.


>
> While the specification does not preclude the possibility that a host
> object may be implemented with native semantics, it nonetheless
> defines a host object:
>
> | 4.3.8
> |  host object
> |  object supplied by the host environment to complete the
> |  execution environment of ECMAScript.
> |
> |  NOTE Any object that is not native is a host object.
>
> And that means that `alert`, `window`, `document`, XMLHttpRequest, are
> all host objects. Whether or not those objects are implemented as
> native ECMAScript objects is another matter altogether.
>

This is the crux. The language there is indeed poorly phrased. But native
objects are not host objects.

Indeed, it is so poorly phrased that perhaps we should add an errata to
clean this up. Sigh. cc'ing es5-discuss.


>
> It seems the the spec is wrong and that you have misinterpreted it. I
> believe that instead it should be written:
>
>
Text missing?



>
> >
> >
> >> Implementations don't agree; when calling `Object.prototype.toString`
> >> with a host object, the result will often be one of those values.
> >>
> >>  Object.prototype.toString.call(alert);
> >>
> >> results either "[object Function]" or "[object Object]". That behavior
> >> is allowed in ES3, but why not in ES5? ES5 seems to defy what most (if
> >> not all) implementations do there.
> >>
> >
> > As far as ES5 is concerned, an implementation is perfectly allowed to
> have
> > alert's [[Class]] be "Function", iff alert on that platform is a
> function,
> > i.e., behaves as a function is obligated to behave. In fact, I think that
> is
> > the most reasonable choice. If alert on a given implementation is instead
> a
> > host object, then it has almost no rules governing its behavior. We don't
> > wish it to be able to claim otherwise.
> >
> > I have not yet seen any draft of the new WebIDL bindings for ES5. These
> may
> > very well determine whether alert is a host object or a native function,
> as
> > far as w3c specs are concerned. Either decision would be allowed by ES5.
> >
> >
> >>
> >> Some host objects including `alert` are implemented as a native
> >> ECMAScript objects (`alert instanceof Function`). In that case, the
> >> [[Class]] property should be "Function".
> >>
> >
> >
> > (alert instanceof Function) is not a reliable test in either direction.
>
> No of course not.
>
> A
> > host object as well as a native non-function is perfectly free to inherit
> > from Function.prototype and thus pass this test. And an actual function
> may
> > be an instance of Function constructor from another frame and so fail the
> > test. But yes, iff alert is indeed a native function, it's [[Class]]
> should
> > be "Function".
> >
>
> Therein lies a contradiction: A host object here may be a function.
>

No it may not. A host object may be callable and it may inherit from
Function.prototype, but it may not be a function.


> Yet because it is a host object, that same object's [[Class]] must not
> be "Function", and yet again, since it is a function, and any function
> must have [[Class]] "Function", then this object's [[Class]] must be
> "Function".
>
> >
> >
> >>
> >> However according to ES5 specs, any host object must not be withing
> >
> > the set of values that are not allowable and so the assertion could be
> >> made that if any object has a [[Class]] that is one of those values,
> >> then the object is not a host object.
> >
> >
> > Yes, that is intentional.
>
> Then it will fail today, as
>
> javascript: alert(({}).toString.call(alert))
>
> - will result "[object Object]" or "[object Function]"
>

1) No current implementations claim ES5 conformance.
2) On ES5 conformant implementations, alert may well be a function in which
case the second result will remain correct.



>
> >>
> >
> > Surely you meant "_toString.call(m)"? And of the two names above, I think
>
> Yes.
>
> > asHostObject is more appropriate, as it applies whether m is method-like
> or
> > not.
> >
> > Other than those typos, this code looks fine. Once one has determined
> that
> > the platform is ES5, I think this code is perfectly good to use.
> >
>
> No, definitely not. It is not interoperable. Results vary depending on
> the browser and host object in question. It does not reliably indicate
> if an object is a host object, and in fact, that is too generous,
> because in none of the implementations I tested will it indicate that
> `alert` is a host object, which it is.
>

I said "Once one has determined that the platform is ES5". None are yet
available except Besen. Have you tested on an ES5 implementation?


>
> >
> >> However, we know that won't hold true in many cases more than just
> >> `alert`.
> >>
> >
> > Any implementation in which this doesn't hold is not a conformant ES5
> > implementation, and shouldn't claim otherwise.
> >
>
> All or most browser implementations will result either "Function" or
> "Object" for [[Class]] property of `alert`, and so the above function
> (typos fixed) would fail in every implementation.
>

Again "Once one has determined that the platform is ES5". None of the
current browser implementations are.


>
> It seems that the specification should change to reflect what
> implementations do and what is wanted by other parts of the spec, as
> suggested above.
>
> Garrett
>



-- 
    Cheers,
    --MarkM
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to