- From: Cameron McCormack <cam@mcc.id.au>
- Date: Wed, 7 Oct 2009 21:57:52 -0700
- To: public-script-coord@w3.org
On Monday, Brendan, Allen, Mark, Jonas had a second ad hoc meeting to discuss Web IDL. Below are some rambling notes. I didn’t agree with the part of Allen’s analysis of overloading that claimed that it currently requires expensive overload resolution whenever a function is called (the implementation should know ahead of time exactly what set of ES types correspond to which overloaded operation). There was agreement though about the “impedence mismatch” when considering ES as the most important language binding, and using union types seemed like a plausible way of doing this. Specs currently tend to consider them in prose as the same operation/function anyway. Moving to union types would help discourage certain poor designs, such as canvas’ createImageData(), where certain arguments change their meaning depending on how many are passed. If we restrict ourselves to union types plus the current way of specifying optional arguments, then it does make some patterns more difficult to specify. In particular, if with the current overload mechanism we had void f(in DOMString s); void f(in DOMString s, in float x, in float y); void f(in Element e); void f(in Element e, in float x, in float y); then we’d need need to write this as void f(in DOMString | Element a, in optional float x, in optional float y); thus allowing two arguments to be passed, if you just look at the IDL, and then prose would be required to disallow the two argument call. We could go back to the way [Optional] used to be specified, which meant that that argument and all following could be omitted, but I found that to be a bit unclear. (Currently, overloading is required in the spec to handle this case.) Another thing I just noticed is that it doesn’t allow you to specialise the return type depending on which overload is invoked. I can’t remember seeing any web API that currently has different return types on overloaded operations. With this union types model, Null would become a built-in type in the IDL. As in the current spec, the string type (DOMString; maybe we can reconsider renaming it again) would not have null as one of its values. A union type would be needed to allow null as a distinct value, e.g.: attribute (DOMString | Null) x; and the ‘?’ suffix currently used to denote a nullable type could be syntactic sugar for that: attribute DOMString? x; (And of course typedefs could be used to make union types more usable.) We talked about having an Undefined type in the IDL, too, but I’m not sure whether we came to an agreement on that. If we did have it, then we should distinguish the case where the Undefined type is accepted as an argument value with the case where the argument is omitted. The thought is that there are few APIs where it makes sense to distinguish null and "" when accepting a DOMString (getAttribute being a notable one). But we will need to check. There are two possibilities on how ES values are coerced to DOMString by default: A) null is converted to "" anything else is converted using the String constructor B) everything is converted using the String constructor If an analysis shows that the former covers most cases (majority? plurality?) then we would go with that and also not allow overriding this in the IDL as you can do with [Null] (or [TreatNullAs], as it became). With regards to how the undefined value should be coerced to a string, Jonas said (paraphrasing): A lot of people have argued that we should always use the String constructor so undefined gets converted to "undefined" (and similarly for null). I see logic in that too. What makes the least amount of sense is what we do in Gecko, where null comes "" and undefined becomes "undefined". I think we should recommend converting both to the empty string and seeing what people say. We can use union types to handled undefined differently if necessary. I think IE generally stringifies both null and undefined. And Mark said: We shouldn’t be considering converting null to "" but undefined to "undefined". Later discussion, assuming that there was no Undefined type in the IDL, suggested that the Null IDL type could be specified as either null or undefined in ES, but when returned from the implementation to ES would always be denoted using null. We also discussed removing the null value from interface types, which would require IDL writers then to use union types to explicitly allow null. For example: attribute Node? firstChild; /* or (Node | Null) */ void appendChild(in Node n); where firstChild can be null, but the value passed to appendChild cannot. We’d define a TypeError (or something) to be thrown if null was passed to appendChild here. Due to trouble with catchalls clashing with properties that exist on an object, we agreed that new APIs shouldn’t (mustn’t?) use these. Name getters would need to remain in the spec to handle current APIs that use them, such as localStorage. We would change them back to extended attributes ([NameGetter] and so on) since they wouldn’t be part of the IDL language proper. Similarly for callers, which seem to be an anti- pattern. We came up with five (or four) categories for Web IDL features to be classified as being members of, in order to manage functionality that we don’t want to perpetuate: 1. Web IDL “the good parts” Features that aren’t controversial. Mark wanted to ensure that this set of features was implementable in ES5 strict code. Brendan thought that array-like objects (i.e., the use of index getters) should fall in this category too, even though it is not possible to write array-like objects in ES5 currently. 2. De jure parts of the spec required for legacy support This would include catchalls (i.e., name getters). New APIs must not use features in this set, but must implement them as specified. 3. “Deprecated” Same as category 2, but that it’s expected that the features could be removed from the platform (and Web IDL) at some point in the future. (This category might be empty, and might as well be removed since they can just be category 2 features that are removed in a future revision of the spec.) 4. Something like ES5’s Appendix B Not normative. These would be advisory notes about things implementations might want to do for compatibility, but it would be up to the implementor to determine whether it was required. If deemed required, then the implementor would follow the definitions in this section (that is, it’s defined how to do it, but optional whether it is required). document.all falsey-ness was considered to be in this category, although currently that behaviour is specified in HTML5, not by virtue of any Web IDL feature. 5. Things considered for standardisation but rejected, and why Also not normative, and requirements wouldn’t be listed at all. (Not sure if any features were deemed to be in this category.) Mark wondered whether there should be both [Supplemental] and the ‘implements’ statement, since both effectively augment the type being supplemented (or the type on the LHS of the ‘implements’), and might cause the same changes to an interface’s prototype object (under a certain design of flattening multiple inheritance to single inheritance prototype chains). I had some issues with [Supplemental] effectively allowing an interface to lose members depending on which set of specs you consider when generating a Java interface, which would cause binary compatibility problems. (You want to only allow methods to be added to an interface.) In Java you handle these cases with mixin interfaces, as is currently done with various DOM specs (e.g. DocumentCSS, DocumentView). I think it might be better to allow these to have unique interface names, like DocumentCSS, but with an extended attribute that indicates explicitly what prototype object is being supplemented with new properties — maybe: [Supplemental] Document implements DocumentCSS; or so. Those of us who were able to stay until the end of the meeting (all but Allen) were happy with a few initial recommendations, but I unfortunately don’t have a note of them. I believe they included: * Not allowing callable objects in future APIs * Not allowing inheritance DAGs (only trees) and possibly also not allowing catchalls in future APIs, but I still need slightly more convincing for that; despite problems of clashing namespaces, it seems like a handy pattern for script authors. Those who attended: please chime in with clarifications/corrections. Thanks, Cameron [1] http://en.wikipedia.org/wiki/LOTE -- Cameron McCormack ≝ http://mcc.id.au/
Received on Thursday, 8 October 2009 04:58:31 UTC