What about functions that take two or more independent optional arguments, 
where sometimes you want to omit the first argument while providing the second?

For example, in the ECMAScript Internationalization API:

   Intl.Collator = function(localeList, options) { ... }

currently fills in default values for both localeList and options if they're 
undefined or not provided. The localeList parameter comes first because most 
applications will want to specify it, while the options are more optional. Some 
rare applications however may be OK with the browser's default locale and still 
need to specify options. In that case, the current spec of the 
Internationalization API lets them use

new Intl.Collator(undefined, {usage: "search"});

It seems the current proposal for optional arguments would not let us use

   Intl.Collator = function(localeList = defaultLocaleList, options = {}) { ... 
}

because undefined as the argument value would prevent the default value from 
being used, and there's no good way for the caller to say "please use the 
default value for this non-trailing argument".

Norbert


On Apr 12, 2012, at 20:38 , Russell Leggett wrote:

> The examples cited are arguably cases where the built-in behaviour is 
> unintuitive to many JavaScript developers, because it doesn't match their 
> expectation with user code functions and most other built-ins.  I don't view 
> any of the cases listed as validation that we would *want* that behaviour by 
> default, just that there are a non-zero number of cases where it exists today.
> 
> > I suggest that the appropriate way to think of about the current behavior, 
> > in the context of ES6, is that function f(a) {...} is equivalent to 
> > function f(a=undefined) {...}
> > In other words, there is a default initialization expression, if one is not 
> > specified. So, f() and f(undefined) appear to produce the same result.
> 
> This is a good way of explaining the proposed semantics, but...
> 
> > But I see why somebody calling a function defined as function(a={ }){...} 
> > explicitly as f(undefined) would expect to trigger the default  value 
> > initializer.
> 
> Right.  This is exactly the sort of thing I'm worried about, and seems like 
> the practical common case for default values.
> 
> 
> 
> >> 2) The fact that JavaScript (at least for user objects) currently doesn't 
> >> differentiate between missing arguments and undefined arguments is a nice 
> >> simplifying rule in the language that is easy to understand..
> 
> > It does differentiate, at least in regard to the arguments object.
> 
> True.  But this is uncommon enough as to not be something most developers 
> deal with.  Default values aim to be a much more commonly used tool.
> 
> 
> 
> > > 3) The example above, of wanting to have an API that allows explicitly 
> > > passing in undefined to override a default value, seems outside of the 
> > > common case (out of curiosity - are there any realistic example of 
> > > this?).  If truly desired, it is easy to not use default values.  But the 
> > > common case seems more likely to be to emulate what is done today - and 
> > > avoid having any undefined values flow into the API call.
> 
> > Why is the example, outside of common sense.  It is a straightforward 
> > function to fill every element of an array with a common value. Undefined 
> > is certain something that can be stored in arrays so why wouldn't there be 
> > situations where where you would want to pass undefined.  Particularly if 
> > the fill function was written by an unreformed Java programmer who used a 
> > peculiar default fill value.
> 
> The last point was why I considered it outside of the common case.  It seems 
> unusual to intentionally want to fill with null by default, but still allow 
> overriding with an undefined fill.  Not impossible, but I would expect this 
> to be rare enough that I don't mind making it the one case where default 
> values can't be used.
> 
> > I agree that there is some confusion among some JS programmer about the 
> > current missing argument default value rules.  However, I don't think what 
> > you are suggesting is going to reduce that confusion.  I think it will 
> > increase it.
> 
> At the end of the day - I see value in enabling the patterns developers are 
> using today to be refactorable into default values.  I worry that the current 
> proposed semantics are too far away from what is used today to make that 
> practical.
> 
> Of course, there is enough inconsistency in what is used currently anyway - 
> so this may be a difficult goal to achieve fully.  But I suspect that 
> treating undefined the same as not present at least keeps things close enough 
> the common forms below could reasonably consider migrating to default values.
> 
> // All fairly common..
> if(!param) { param = 3; }
> if(param == null) { param = 3; }
> if(typeof param == 'undefined') { param = 3; }
> param = param || 3;
> var param = arguments[1] || 3;
> 
> // Not sure I've ever seen this... which seems to be the proposed default 
> value semantics
> if(arguments.length < f.length) { param = 3; }
> 
> 
> At first the answer to this didn't really matter to me, because how often 
> does someone pass undefined to a function like foo(undefined). I know I 
> don't, though I'm sure it happens occasionally. Then I thought about it and 
> realized that it happens in my code all the time, just not like that. A much 
> more common case is a pass through of an argument to another function.
> 
>     function fadeIn(duration=200){...}
>     function fadeOut(duration=200){...}
>     function fadeToggle(duration){
>         if(visible){
>             fadeOut(duration);
>         }else{
>             fadeIn(duration);
>         }
>     }
> 
> Here, the argument duration is always passed through fadeToggle to fadeIn or 
> fadeOut. Someone writing fadeIn would always expect to have a default of 200. 
> fadeToggle does not care about the duration so much as it wants to pass it on 
> and use the defaults of the functions it calls. If passing undefined does not 
> trigger the default, it would have to be rewritten like:
> 
>     function fadeToggle(duration){
>         var hasDuration = typeof duration != "undefined";
>         if(visible){
>             if(hasDuration){
>                 fadeOut(duration);
>             }else{
>                 fadeOut();
>             }
>         }else{
>             if(hasDuration){
>                 fadeIn(duration);
>             }else{
>                 fadeIn();
>             }
>         }
>     }
> 
> Given this, I would probably just stick to putting
> 
>     duration = duration || 200;
> 
> at the top of the function.
> 
> - Russ
> 
> 
> 
> 
> 
>  
> 
> Luke
> 
> 
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to