- From: Cameron McCormack <cam@mcc.id.au>
- Date: Fri, 23 Dec 2011 12:38:36 +1100
- To: "public-script-coord@w3.org" <public-script-coord@w3.org>
- CC: Jonas Sicking <jonas@sicking.cc>, Boris Zbarsky <bzbarsky@mit.edu>, Lachlan Hunt <lachlan.hunt@lachy.id.au>, Allen Wirfs-Brock <allen@wirfs-brock.com>, Anne van Kesteren <annevk@opera.com>, Brendan Eich <brendan@mozilla.org>
In the thread beginning at http://www.w3.org/mid/4E2580C8.6050106@lachy.id.au we came to the conclusion that we would make explicit undefined values passed as optional arguments be treated the same as if the argument was not actually passed. So with void f(long x, optional long y); calling f(0, undefined) would be the same as just calling f(0). There were two arguments for doing this: one was that some thought it better to check against undefined for missing argument values rather than looking at arguments.length, the other was that it was needed to solve problems with querySelector() from the Selectors API and with XMLHttpRequest.open(). For the querySelector() case, the spec used to say something like: NodeList querySelector(DOMString a, Element b); NodeList querySelector(DOMString a, optional sequence<Node>? b); Before the recent overloading model changes, passing undefined as the second argument would result in a TypeError being thrown, because undefined wasn't considered to be an exact match of either of those two types. Allowing undefined to be treated as the lack of a specified argument solved that problem. Now, though, I have made undefined match nullable types, so treating undefined as an omitted argument is not necessary. For XHR.open(), we need to treat calls like xhr.open(method, url, async, undefined, undefined); the same as xhr.open(method, url, async); since some content relies on this. If we stop treating undefined as an omitted argument, then the only way you could write this in IDL would be: void open(DOMString method, DOMString url, optional boolean async, optional any user, optional any password); and to then handle in prose the user/password arguments so that undefined means "don't override the user/password from the url", which is what null means. Otherwise, we could introduce a new [TreatUndefinedAs=MissingArgument] extended attribute. I am not aware of any other APIs that require this. There are a few reasons why I'd like to reverse the undefined treatment: * Erik Arvidsson's point[1] that ES6 default argument values will not be treating explicit undefined as an omitted argument. * The complications it brings to the overloading model compared to only checking for arguments.length, which is already done in the overload resolution algorithm anyway. * The fact that the behaviour is different from various other places where undefined is handled (non-optional arguments, and conversion of JS values to IDL values in general). I think there was a fine balance of arguments for versus the convenience of being able to make calls like: function f(options) { xhr.open("get", options.url, true, options.user, options.password); } I feel like the alignment with ES6 default arguments tips the balance the other way. I will make this change soon unless there are strong arguments for keeping the status quo. Thanks, Cameron [1] http://www.w3.org/mid/CAJ8+GoikEne_g4DnHa4ihdROfXy+xqq6mC2aDTB=Co1aj0KDnw@mail.gmail.com
Received on Friday, 23 December 2011 01:39:17 UTC