Re: Reconciling handling of optional arguments and handling of default values across ES and webidl

Boris Zbarsky wrote:
> 1) In the new setup, I believe this is valid IDL:
>
> void foo(optional long arg1, long arg2);

Yes.

> Is this purposeful?

Yes, so that you can pass undefined for arg1 and have the prose do 
something based on that.

> It looks at first glance like this function should have length 2,
> since in
> http://dev.w3.org/2006/webapi/WebIDL/#dfn-effective-overload-set step
> 5.7 we'll start with i == 1 and discover that "argument i of X" (does
> it mean "X's argument at index i"?) is not optional, so the shortest
> element of the overload set will have two arguments, right?

Yes.  Since arg2 must be specified, I think it makes more sense to have 
length be 2 rather than 0.  WDYT?

> 2) I'm not convinced about the changes to the variadic handling. In
> particular, consider this function:
>
> void foo(long... argList);
>
> and an invocation of it like so:
>
> foo(5, undefined, 6);
>
> when the effective overload set is computed for this call, we get the
> following tuples:
>
> <foo, (long), (true)>
> <foo, (), ()>
> <foo, (long, long), (true, true)>
> <foo, (long, long, long), (true, true, true)>
>
> then we remove all but the last entry from the list. Now we start doing
> the argument conversions and invoke the callee with the values 5,
> |special value "missing"|, 6.
>
> That seems pretty odd to me. Are there use cases for having missing
> variadic args? If not, I'd prefer we keep the old behavior, where all
> the variadics (except perhaps trailing undefined, which would simply not
> be passed on to the callee?) are coerced to the right type. Otherwise we
> have to fix all specs using variadics to deal with the "missing" case...

Yes, I think that's fair enough.  If we feel we do want to support 
"explicit undefined => missing optional argument" in variadic positions 
later we can make "(optional long... argList)" or something mean that.

It's also kind of weird to treat trailing undefined differently from 
middle-of-the-variadic-arguments undefined, though, so I'm inclined to 
have them all get coerced to the argument type.

I'm going need to store the variadic-ness, not just the optional-ness, 
in the tuples for that, I think.  Change coming soon...

> 3) I don't understand step 10.2 of the overload resolution algorithm.
> Why is this needed, exactly?

If you have

   void f(long x, long y);
   void f(long x, optional Node n);

and you call

   f(0, undefined);

then S is

   { <f_1, (long, long), (false, false)>,
     <f_2, (long, Node), (false, true) > }

just after step 3, and the distinguishing argument index, d, is 1.

Step 10.2 looks at the undefined value that was passed in, matches it 
against the optional Node argument of f_2, and so selects that overload.

> Nits:
>
> 4) There is a typo in "followed only be optional arguments" when talking
> about dictionary types.

Fixed.

> 5) In the above discussion of overload sets for functions with 1
> variadic argument, I assumed that when n == 1, t_{0...n-2} means "empty
> list". It might be worth being more explicit about that somehow... Note
> that this empty list would be added by effective overload set step 5.8
> anyway, so there is no harm in restricting step 5.5.1 to the case when n
>  > 1.

Yes, the t_{0..n-2} is meant to be like t.slice(0, n - 1) if it were a 
JS array.  I agree the notation I'm using there for lists isn't great. 
Hopefully it is clear that it doesn't mean remove two items from the 
end, given the usage in step 5.3 etc., where it's declaring a whole 
list.  But I've added a note in 5.1 to say that it means it leaves off 
the variadic argument.

Received on Thursday, 26 September 2013 09:16:07 UTC