- From: Cameron McCormack <cam@mcc.id.au>
- Date: Thu, 04 Aug 2011 12:50:38 +1200
- To: Lachlan Hunt <lachlan.hunt@lachy.id.au>
- CC: public-script-coord@w3.org, jonas@sicking.cc, bzbarsky@mit.edu, allen@wirfs-brock.com
On 20/07/11 1:04 AM, Lachlan Hunt wrote:
> Refer to discussion in a Mozilla bug 648722 [1].
>
> When undefined in passed to an overloaded function, the overload
> resolution algorithm should not exclude nullable non-primitive types.
Thanks for all the discussion in the thread. It sounds like the
following is what was settled on:
* When undefined is passed, it is always treated the same as if it was
not passed at all.
* Overload resolution is performed after these undefined arguments at
the end of a function call are "dropped".
* Anywhere an undefined would help select a nullable primitive type
during overload resolution, it should help select nullable types
regardless of the inner type. (This would still matter in cases
where explicit undefined is passed in the middle of the argument list,
and later arguments are not undefined.)
I want to run through what that means with some examples. In June I
resolved the open issue about what to do with too few arguments being
passed -- convert from undefined, or throw -- to throw. (I couldn't
find a mail on this list where I announced that resolution; maybe I
forgot to send it.) It might be that treating an explicit undefined as
being like not having passed the argument at all feels inconsistent with
throwing for too few arguments, not sure. Anyway:
void f(in float x, in optional float y);
The two overloads to select between are:
(float)
(float, float)
f() === throw TypeError
f(undefined) === throw TypeError
f(null) === f(0)
f(1) === f(1)
f(1, undefined) === f(1)
f(1, null) === f(1, 0)
void f(in float x, in float? y);
There is only a single "overload":
(float, float?)
f() === throw TypeError
f(undefined) === throw TypeError
f(null) === throw TypeError
f(1) === throw TypeError
f(1, undefined) === throw TypeError
f(1, null) === f(1, null)
void f(in float x, in optional float? y);
Overloads are:
(float)
(float, float?)
f() === throw TypeError
f(undefined) === throw TypeError
f(null) === f(0)
f(1) === f(1)
f(1, undefined) === f(1)
f(1, null) === f(1, null)
void f(in float x);
void f(in float x, in float y, in float z);
Overloads are:
(float)
(float, float, float)
f() === throw TypeError
f(undefined) === throw TypeError
f(null) === f(0)
f(1) === f(1)
f(1, undefined) === f(1)
f(1, null) === throw TypeError
f(1, 2) === throw TypeError
f(1, 2, undefined) === throw TypeError
f(1, 2, null) === f(1, 2, 0)
f(1, undefined, undefined) === throw TypeError
f(1, undefined, 2) === f(1, NaN, 2)
f(1, null, 2) === f(1, 0, 2)
And finally for the API at hand:
Element querySelector(in DOMString a, in optional Element b);
Element querySelector(in DOMString a, in sequence<Node>? b);
Overloads are:
(DOMString)
(DOMString, Element)
(DOMString, sequence<Node>?)
querySelector() === throw TypeError
querySelector(undefined) === throw TypeError
querySelector(null) === querySelector("null")
querySelector("a", undefined) === querySelector("a")
querySelector("a", null) === querySelector("a", (sequence<Node>?)null)
Let me know your thoughts.
Received on Thursday, 4 August 2011 00:51:20 UTC