- 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