W3C home > Mailing lists > Public > public-script-coord@w3.org > July to September 2013

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

From: Domenic Denicola <domenic@domenicdenicola.com>
Date: Fri, 27 Sep 2013 05:25:50 +0000
To: Cameron McCormack <cam@mcc.id.au>
CC: Boris Zbarsky <bzbarsky@MIT.EDU>, Allen Wirfs-Brock <allen@wirfs-brock.com>, Brendan Eich <brendan@mozilla.com>, "public-script-coord@w3.org" <public-script-coord@w3.org>
Message-ID: <B837832F-8DC9-4B49-B177-A61CD8649402@domenicdenicola.com>


> On Sep 26, 2013, at 5:17, "Cameron McCormack" <cam@mcc.id.au> wrote:
> 
> 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?

This does not match ES6, where it would be zero if you wrote

function foo(arg1 = undefined, arg2) {
  if (arg2 === undefined) throw new TypeError("arg2 required");
}

I suppose you could not map "optional" to "= undefined", but that seems most natural, and fits well with how I assume default arguments in WebIDL should be mapped to ES.

> 
>> 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 Friday, 27 September 2013 05:26:23 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:37:50 UTC