Re: [PrototypeRoot]

2009-08-06 Thread Garrett Smith
On Mon, Jun 22, 2009 at 4:49 PM, Ian Hicksoni...@hixie.ch wrote:
 On Sun, 21 Jun 2009, Garrett Smith wrote:
 On Sat, Jun 20, 2009 at 12:43 AM, Ian Hicksoni...@hixie.ch wrote:
  On Sat, 20 Jun 2009, Garrett Smith wrote:
 
  I still want to know: Why would a program want to know the object's
  [[Class]]?
 
  It shouldn't, but [[Class]]es are exposed by ECMAScript objects in
  their toString() method and thus if we want to ensure universally
  consistent behaviour we have to define this.

 No, that is all untrue.

 Which part is untrue?


1) The [[Class]] property is not exposed in the object's toString.
[[Class]] is exposed in Object.prototype.toString. This is very easy
to demonstrate.
2) The decision to define this is a choice. That choice as being (part
of) a conclusion to the argument: How to define universally consistent
behavior.

It is possible to define universally consistent as having toString
to be a callable object for host objects and allowing for enough
wiggle room for things to not break at every possible change (change =
browsers, versions, code contexts). It is not necessary to define any
sort of prototype chain (e.g. which toString shadows which other
toString).  That lacks good design sense.

 I said three things:

  - A program shouldn't want to know an object's [[Class]]
  - [[Class]] is exposed by ECMAScript in an object's toString() method
  - If we want to ensure universal behaviour we have to define this

 You seem to agree with the second point, as you say:

 The [[Class]] property is exposed in Object.prototype.toString.

 You presumably agree with the first point since you were asking for a
 reason and implying there wasn't one.


I haven't actually seen a good reason.

 Do you disagree that we need to define things to get universal behaviour?


No. Do you disagree that design ought to be flexible and extensible?

Is universal behavior necessary though? There are many things that
browsers will do.  Browser vendors can and do innovate proprietary
useful features. Sometimes its bad. Okay, often it is bad. As a whole,
if done right, implementations can innovate new ideas. It does not all
need to come from HTML 5.


 Ensuring universally consistent behavior would require that *all
 browsers* behave exactly the same.

 Right, that's the goal.


That is easy:
var objString = Object.prototype.toString.call( hostObj );
Assert.isTypeOf( objString, string );

It is more complicated than what we have today (nothing), but adds a
little stability to the way objects behave. It says that a string can
be obtained from an object. That is not guaranteed today.

A program that makes assertions on that string's *value* would be
locking itself in to what the API is today. This limits future APIs by
locking them in to what web pages use.  Authors should not be
discouraged from using toString(), but programs that make decisions
based on the value it returns would be considered unsafe.


 MSIE does not behave that way today and versions of other browsers may
 vary, too.

 Indeed, that's the problem we are trying to fix.



It is not a problem.

The proposed change cannot address all possible host objects or other
host interfaces. I can't address browsers that do not currently behave
that way. On those counts alone, it would be unadvisable for a program
to utilize the [[Class]] for anything other than an error message.

Probably by the time you are done with fixing it, there will be new
interfaces being completed and these interfaces will also need to be
woven in.

The change you are eliciting seems well-intentioned, but serves only
to encourage authors to use strategies that are not advisable.

 To ensure safer, more reliable behavior, define the [[Class]] property
 as being a string value. That way, it would be guaranteed that
 Object.prototype.toString.call( any_object ); would result in string
 value being produced, and an error would not occur.

 As far as I can tell, everyone agrees that [[Class]] should be a string.


 The value of that string should be implementation-dependent.

 That would not lead to a well-defined universal behaviour.


It would most lead to a well-defined universal behavior. It would
define the [[Class]] as being a string value, and so a program could
reasonable expect that:-

Object.prototype.toString.call( anotherObject )

- would return a string value and would not throw errors. That is is
not a lot expect, but as a testing requirement, it might help prevent
bugs.


 This makes the feature flexible, extensible, and provides the
 aforementioned benefits of interfaces over classes (e.g. mixin style
 behavior with implementation-specific host objects).

 It seems that the [[Class]] value has nothing to do with the flexibility,
 extensibility, and mixin style behaviour of objects.


 Providing a suggestion to implementors as to what that value might be
 would be harmless.

 And mostly useless, if they ignore it; if they don't, it might as well be
 a requirement.


Is this (yet 

Re: [PrototypeRoot]

2009-06-22 Thread Ian Hickson
On Sun, 21 Jun 2009, Garrett Smith wrote:
 On Sat, Jun 20, 2009 at 12:43 AM, Ian Hicksoni...@hixie.ch wrote:
  On Sat, 20 Jun 2009, Garrett Smith wrote:
 
  I still want to know: Why would a program want to know the object's 
  [[Class]]?
 
  It shouldn't, but [[Class]]es are exposed by ECMAScript objects in 
  their toString() method and thus if we want to ensure universally 
  consistent behaviour we have to define this.
 
 No, that is all untrue.

Which part is untrue?

I said three things:

 - A program shouldn't want to know an object's [[Class]]
 - [[Class]] is exposed by ECMAScript in an object's toString() method
 - If we want to ensure universal behaviour we have to define this

You seem to agree with the second point, as you say:

 The [[Class]] property is exposed in Object.prototype.toString.

You presumably agree with the first point since you were asking for a 
reason and implying there wasn't one.

Do you disagree that we need to define things to get universal behaviour?


 Ensuring universally consistent behavior would require that *all 
 browsers* behave exactly the same.

Right, that's the goal.


 MSIE does not behave that way today and versions of other browsers may 
 vary, too.

Indeed, that's the problem we are trying to fix.


 To ensure safer, more reliable behavior, define the [[Class]] property 
 as being a string value. That way, it would be guaranteed that 
 Object.prototype.toString.call( any_object ); would result in string 
 value being produced, and an error would not occur.

As far as I can tell, everyone agrees that [[Class]] should be a string.


 The value of that string should be implementation-dependent.

That would not lead to a well-defined universal behaviour.


 This makes the feature flexible, extensible, and provides the 
 aforementioned benefits of interfaces over classes (e.g. mixin style 
 behavior with implementation-specific host objects).

It seems that the [[Class]] value has nothing to do with the flexibility, 
extensibility, and mixin style behaviour of objects.


 Providing a suggestion to implementors as to what that value might be 
 would be harmless.

And mostly useless, if they ignore it; if they don't, it might as well be 
a requirement.


 Mandating the *value* of that [[Class]] property creates a brittle, 
 fragile API.

It creates a well-defined, consistent and predictable API. This is 
desireable.


 Authors will utilize the specification to write code to that value to 
 create code that is as brittle and fragile as the API it uses and works 
 in fewer implementations, including browsers that are in widespread use 
 today.

I think it is woefully optimistic to expect any significant number of 
authors to read the specification.


  Even if a program could know the [[Class]], what's to say it won't 
  change in the future?
 
  The specs we write.
 
 No, the specifications do change.

The specifications we write are the ones that are to say that it won't 
change. If the specifications say it changes, then it changes. My point is 
that it is up to the specifications we write to make this not change.


 The introduction of HTMLFormControls collection, for example, was a 
 new one. There is a possibility of a StaticNodeList or HTMLLinks 
 collection in the future. The interfaces implemented by an object vary 
 between implementations and evolve over time.

So long as we converge on a stable and well-implemented platform, early 
changes are not a problem.


  Given a particular object, can that object's [[Class]] property 
  change in the future? If it there is an object that exists, say, some 
  sort of HTMLCollection, and it becomes desirable to make more 
  specific behavior, say HTMLFormControlsCollection, what would the 
  code that expects the object's class to be HTMLCollection need to do 
  to continue working in multiple versions of multiple browsers?
 
  We would have to test to see if any pages rely on it; if they do, we'd 
  have to make sure we don't change the [[Class]] somehow.
 
 That sounds like a brittle feature.

It is no more or less brittle than anything else in the Web platform as 
far as I can tell. Any API could change; it is our responsibility to make 
sure that we don't change APIs that pages rely on.


 An object's [[Class]] feature should ideally provide specific, detailed 
 information, and should be used *only* in debugging. Never rely on it.

It would be wonderful if that were the case.


  Given all these reasons, it would still seem like a bad idea to 
  program to an object's [[Class]]. Instead, the interface should be 
  programmed tot using feature detection.
 
  Yup.
 
 OK. Strings are not a substitute for capability checks. The [[Class]] in 
 particular has very little potential to return information about what an 
 object can do. It would be a very risky design decision to make 
 inferences solely on the [[Class]] value.

Yup.


 We seem to be eye to eye on that much but I think the API design has 
 gone too 

Re: [PrototypeRoot]

2009-06-21 Thread Garrett Smith
On Sat, Jun 20, 2009 at 12:43 AM, Ian Hicksoni...@hixie.ch wrote:
 On Sat, 20 Jun 2009, Garrett Smith wrote:

 I still want to know: Why would a program want to know the object's
 [[Class]]?

 It shouldn't, but [[Class]]es are exposed by ECMAScript objects in their
 toString() method and thus if we want to ensure universally consistent
 behaviour we have to define this.


No, that is all untrue.

The [[Class]] property is exposed in Object.prototype.toString.

Ensuring universally consistent behavior would require that *all
browsers* behave exactly the same. MSIE does not behave that way today
and versions of other browsers may vary, too.

To ensure safer, more reliable behavior, define the [[Class]] property
as being a string value. That way, it would be guaranteed that
Object.prototype.toString.call( any_object ); would result in string
value being produced, and an error would not occur. The value of that
string should be implementation-dependent. This makes the feature
flexible, extensible, and provides the aforementioned benefits of
interfaces over classes (e.g. mixin style behavior with
implementation-specific host objects).

Providing a suggestion to implementors as to what that value might be
would be harmless.

Mandating the *value* of that [[Class]] property creates a brittle,
fragile API. Authors will utilize the specification to write code to
that value to create code that is as brittle and fragile as the API it
uses and works in fewer implementations, including browsers that are
in widespread use today.


 Even if a program could know the [[Class]], what's to say it won't
 change in the future?

 The specs we write.

No, the specifications do change. The introduction of
HTMLFormControls collection, for example, was a new one. There is a
possibility of a StaticNodeList or HTMLLinks collection in the
future. The interfaces implemented by an object vary between
implementations and evolve over time.



 Given a particular object, can that object's [[Class]] property change
 in the future? If it there is an object that exists, say, some sort of
 HTMLCollection, and it becomes desirable to make more specific behavior,
 say HTMLFormControlsCollection, what would the code that expects the
 object's class to be HTMLCollection need to do to continue working in
 multiple versions of multiple browsers?

 We would have to test to see if any pages rely on it; if they do, we'd
 have to make sure we don't change the [[Class]] somehow.

That sounds like a brittle feature. An object's [[Class]] feature
should ideally provide specific, detailed information, and should be
used *only* in debugging. Never rely on it.



 Given all these reasons, it would still seem like a bad idea to program
 to an object's [[Class]]. Instead, the interface should be programmed tot
 using feature detection.

 Yup.


OK. Strings are not a substitute for capability checks. The [[Class]]
in particular has very little potential to return information about
what an object can do. It would be a very risky design decision to
make inferences solely on the [[Class]] value.

We seem to be eye to eye on that much but I think the API design has
gone too far.

Defining the value of the [[Class]] encourages that value to be used
in code. That is bad! Programmers who rely on that value will not
rightly blame themselves for their design mistakes. Instead, they will
look externally, read the standard, and blame the implementations that
don't do what their perfectly standards-compliant program expects

Garrett



Re: [PrototypeRoot]

2009-06-20 Thread Cameron McCormack
Ian Hickson:
 I don't really mind exactly what the solution is; my only concern here 
 would be that I'd be throwing [PrototypeRoot] around a lot.

Acknowledged.  If you can propose a way of defining this without needing
to use [PrototypeRoot] a lot, that’d help.

 (I assume with PrototypeRoot that the most-derived interface that
 inherits from such an interface is automatically promoted to being the
 [[Class]]?)

That’s right.

-- 
Cameron McCormack ≝ http://mcc.id.au/



Re: [PrototypeRoot]

2009-06-20 Thread Garrett Smith
On 6/20/09, Cameron McCormack c...@mcc.id.au wrote:
 Ian Hickson:
 I don't really mind exactly what the solution is; my only concern here
 would be that I'd be throwing [PrototypeRoot] around a lot.

 Acknowledged.  If you can propose a way of defining this without needing
 to use [PrototypeRoot] a lot, that’d help.

 (I assume with PrototypeRoot that the most-derived interface that
 inherits from such an interface is automatically promoted to being the
 [[Class]]?)

 That’s right.


I still want to know: Why would a program want to know the object's [[Class]]?

Even if a program could know the [[Class]], what's to say it won't
change in the future?

Given a particular object, can that object's [[Class]] property change
in the future? If it there is an object that exists, say, some sort of
HTMLCollection, and it becomes desirable to make more specific
behavior, say HTMLFormControlsCollection, what would the code that
expects the object's class to be HTMLCollection need to do to continue
working in multiple versions of multiple browsers?

Microsoft has had vendor extensions in IE prior to the w3c dom level
1. Such vendor extensions don't fall nicely into type heirarchies, but
are well-suited towards mixin style design, which is possible with
interfaces.

Also, there will always be more browsers that implement an interface,
but don't give that object the [[Class]] property that is specified in
web IDL.

Given all these reasons, it would still seem like a bad idea to
program to an object's [[Class]]. Instead, the interface should be
programmed to using feature detection.

Even the [[Class]] were widespread-adopted, it would be a bad idea to
do that. I don't know what I am missing, but it doesn't seem to have
been explained on this thread.

Why do you want that?

Garrett

 --
 Cameron McCormack ≝ http://mcc.id.au/





Re: [PrototypeRoot]

2009-06-20 Thread Ian Hickson
On Sat, 20 Jun 2009, Cameron McCormack wrote:

 Ian Hickson:
  I don't really mind exactly what the solution is; my only concern here 
  would be that I'd be throwing [PrototypeRoot] around a lot.
 
 Acknowledged.  If you can propose a way of defining this without needing
 to use [PrototypeRoot] a lot, that’d help.

Given an object and a list of interface that it implements, remove 
interfaces from the list that match any of the following conditions:

  - the interface was on the right hand side of an 'implements' clause the 
left hand side of which lists an interface that the object implements

  - the interface is inherited from another interface the object 
implements

  - the interface has [NoInterfaceObject]

...you should be lift with one interface. Use its name as the [[Class]].

Are there any objects where that leaves an ambiguity?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

Re: [PrototypeRoot]

2009-06-20 Thread Ian Hickson
On Sat, 20 Jun 2009, Garrett Smith wrote:
 
 I still want to know: Why would a program want to know the object's 
 [[Class]]?

It shouldn't, but [[Class]]es are exposed by ECMAScript objects in their 
toString() method and thus if we want to ensure universally consistent 
behaviour we have to define this.


 Even if a program could know the [[Class]], what's to say it won't 
 change in the future?

The specs we write.


 Given a particular object, can that object's [[Class]] property change 
 in the future? If it there is an object that exists, say, some sort of 
 HTMLCollection, and it becomes desirable to make more specific behavior, 
 say HTMLFormControlsCollection, what would the code that expects the 
 object's class to be HTMLCollection need to do to continue working in 
 multiple versions of multiple browsers?

We would have to test to see if any pages rely on it; if they do, we'd 
have to make sure we don't change the [[Class]] somehow.


 Given all these reasons, it would still seem like a bad idea to program 
 to an object's [[Class]]. Instead, the interface should be programmed to 
 using feature detection.

Yup.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [PrototypeRoot]

2009-06-19 Thread Cameron McCormack
Cameron McCormack:
  Done:
  
The value of the internal [[Class]] property of a host object is
determined as follows:
  * If the host object implements a single interface, then the value
of the internal [[Class]] property MUST be the identifier of
that interface.

Ian Hickson:
 I think it would make sense to exclude [NoPrototypeObject] interfaces from 
 consideration here.

I assume you mean [NoInterfaceObject]?  Is the reasoning for this that
[NoInterfaceObject] inerfaces are nearly always “mixins”, and so
shouldn’t affect the [[Class]]?

Cameron McCormack:
  Note that this still technically does not mean you can guarantee that
  the NodeList returned by querySelectorAll() has [[Class]] == NodeList,
  since it could be that that host object implements another interface,
  which might be required by another spec, or perhaps just because the
  implementation wants to.

Ian Hickson:
 IMHO this is a problem. I don't think that UA extensions should affect the 
 [[Class]], and I think that other specs should have a way (e.g. 
 [NoPrototypeObject]) of always making sure they don't affect the [[Class]] 
 of existing stuff.

Do you still think it would be bad to use [ProtoypeRoot] on interfaces
like NodeList, to indicate that it is the “main” interface?  That would
be the way, currently, to require a particular [[Class]] that could not
be overridden by having a second interface be implemented.

Thanks,

Cameron

-- 
Cameron McCormack ≝ http://mcc.id.au/



Re: [PrototypeRoot]

2009-03-08 Thread Garrett Smith
On Sat, Mar 7, 2009 at 4:03 PM, Ian Hickson i...@hixie.ch wrote:
 On Sat, 7 Mar 2009, Cameron McCormack wrote:

 Done:

   The value of the internal [[Class]] property of a host object is
   determined as follows:
     * If the host object implements a single interface, then the value
       of the internal [[Class]] property MUST be the identifier of
       that interface.

 I think it would make sense to exclude [NoPrototypeObject] interfaces from
 consideration here.


 Note that this still technically does not mean you can guarantee that
 the NodeList returned by querySelectorAll() has [[Class]] == NodeList,
 since it could be that that host object implements another interface,
 which might be required by another spec, or perhaps just because the
 implementation wants to.

 IMHO this is a problem.

What is the problem?

I don't think that UA extensions should affect the
 [[Class]], and I think that other specs should have a way (e.g.
 [NoPrototypeObject]) of always making sure they don't affect the [[Class]]
 of existing stuff.

An API based on interfaces (the DOM, for example), can only reflect
one interface (at most0 in the [[Class]].

What is your use case for designing a program around having to know
the [[Class]]?

Garrett



Re: [PrototypeRoot]

2009-03-07 Thread Ian Hickson
On Sat, 7 Mar 2009, Cameron McCormack wrote:
 
 Done:
 
   The value of the internal [[Class]] property of a host object is
   determined as follows:
 * If the host object implements a single interface, then the value
   of the internal [[Class]] property MUST be the identifier of
   that interface.

I think it would make sense to exclude [NoPrototypeObject] interfaces from 
consideration here.


 Note that this still technically does not mean you can guarantee that
 the NodeList returned by querySelectorAll() has [[Class]] == NodeList,
 since it could be that that host object implements another interface,
 which might be required by another spec, or perhaps just because the
 implementation wants to.

IMHO this is a problem. I don't think that UA extensions should affect the 
[[Class]], and I think that other specs should have a way (e.g. 
[NoPrototypeObject]) of always making sure they don't affect the [[Class]] 
of existing stuff.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [PrototypeRoot]

2009-03-06 Thread Cameron McCormack
Ian Hickson:
 In that case I would like us to do this (specifically, define [[Class]] 
 for objects that have only one non-[NoPrototypeObject] interface), since 
 that's the majority of them, and it would be better than having to 
 sprinkle [PrototypeRoot] all over the place.

Done:

  The value of the internal [[Class]] property of a host object is
  determined as follows:
* If the host object implements a single interface, then the value
  of the internal [[Class]] property MUST be the identifier of
  that interface. 
* Otherwise, if the host object has a primary prototype interface,
  then the value of the internal [[Class]] property MUST be the
  identifier of that interface.
* Otherwise, no particular value is required to be used for the
  value of the internal [[Class]] property.
   — http://dev.w3.org/2006/webapi/WebIDL/#host-objects

Note that this still technically does not mean you can guarantee that
the NodeList returned by querySelectorAll() has [[Class]] == NodeList,
since it could be that that host object implements another interface,
which might be required by another spec, or perhaps just because the
implementation wants to.  There’s nothing in selectors-api that says
“the object returned from querySelectorAll() must implement the NodeList
interface and no others” (and I don’t think it’d be a good idea to
require that).

-- 
Cameron McCormack ≝ http://mcc.id.au/