This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 23532 - Dealing with undefined
Summary: Dealing with undefined
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: WebIDL (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Cameron McCormack
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 23604
  Show dependency treegraph
 
Reported: 2013-10-16 14:12 UTC by Anne
Modified: 2016-10-21 21:29 UTC (History)
18 users (show)

See Also:


Attachments

Description Anne 2013-10-16 14:12:52 UTC
Domenic proposed these rules:

* If the argument is required, both undefined and missing should give a TypeError
* If the argument is optional, both undefined and missing should trigger the default

I.e. always treat undefined and missing for the same argument identically.
Comment 1 Simon Pieters 2013-10-16 14:30:25 UTC
http://krijnhoetmer.nl/irc-logs/whatwg/20131016#l-503 for context
Comment 2 Glenn Maynard 2013-10-16 14:31:31 UTC
I assumed the idea would be to add a new "required" modifier, since changing every non-optional argument in this way doesn't seem realistic (eg. making alert() throw instead of showing "undefined").  It'd be nice if that's possible, though.
Comment 3 Anne 2013-10-16 14:32:57 UTC
alert() is optional and defaults to "".
Comment 4 Erik Arvidsson 2013-10-16 14:38:28 UTC
This seems good to me.
Comment 5 Glenn Maynard 2013-10-16 15:15:50 UTC
FYI, I was thrown off a bit by the IRC conversation.  The discussion started with "you can't make CSS.escape throw for missing arguments, that's not how JavaScript works" (http://krijnhoetmer.nl/irc-logs/whatwg/20131016#l-409), which ended in "we can do this as long as we make sure it throws if undefined is passed in too".  Actually, tons of functions throw for missing arguments already (WebIDL 4.5.1.1), and passing undefined isn't the same as not passing an argument, so the discussion didn't make any sense.

This ticket is different: it's saying to change all of those existing required arguments to throw if undefined is passed in.  That seems trivially better (passing undefined to xhr.open() and opening "undefined" is never what you meant to do), but I'm not sure it's worth the churn if there's already interop.
Comment 6 Erik Arvidsson 2013-10-16 15:31:38 UTC
(In reply to Glenn Maynard from comment #5)

> ... I'm not sure it's worth the churn if there's
> already interop.

The point is to align with ES optional parameters

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns-runtime-semantics-indexedbindinginitialisation
Comment 7 Glenn Maynard 2013-10-16 15:38:54 UTC
Given that the platform already seems to have interop, shouldn't ES optional parameters be the one doing the aligning?
Comment 8 Erik Arvidsson 2013-10-16 15:44:36 UTC
(In reply to Glenn Maynard from comment #7)
> Given that the platform already seems to have interop, shouldn't ES optional
> parameters be the one doing the aligning?

We talked about this in length several times over the last year. Using arguments.length as the base for optional parameters has too many issues. See es-discuss and notes from multiple f2f tc39 meetings.
Comment 9 Glenn Maynard 2013-10-16 15:57:38 UTC
Since it's what the platform already does, and it seems to have interop across all major browsers, it's probably just too late.  Maybe it's possible to make this happen, but this is a change that would affect hundreds of functions across every API on the platform.  I'd check for buy-in from all major vendors before making such a huge change, or we'll just lose the interop we have now.
Comment 10 Rick Waldron 2013-10-16 18:01:56 UTC
(In reply to Glenn Maynard from comment #9)
> Since it's what the platform already does, and it seems to have interop
> across all major browsers, it's probably just too late.  Maybe it's possible
> to make this happen, but this is a change that would affect hundreds of
> functions across every API on the platform.  I'd check for buy-in from all
> major vendors before making such a huge change, or we'll just lose the
> interop we have now.

Consensus was reached between representatives of all major implementors (Apple, Google, Microsoft and Mozilla all present): https://github.com/rwaldron/tc39-notes/blob/master/es6/2012-07/july-24.md#consensusresolution-2
Comment 11 Boris Zbarsky 2013-10-18 16:20:26 UTC
> Consensus was reached between representatives of all major implementors

With all due respect, the people representing SpiderMonkey there have nothing to do with the methods this bug is talking about changing.  In particular, they do not have any idea of what the compatibility constraints, if any, are.  So their consensus on the ES behavior doesn't mean much for the DOM, unfortunately.

As far as the DOM goes, we've so far failed to make the change of treating undefined as "not passed, use default value" for optional arguments: it's run into compat issues in at least two cases.  We may be able to work around those on the DOM side by modifying the IDL to not use optional arguments (for one we can; for the other it's not even clear yet which API is involved, so it's hard to tell), but there might be more.  It'll be a long slog, with broken websites galore, before the fallout from that change settles, I suspect.

For the case in this bug, it's hard to say anything about compat impact until someone tries it....
Comment 12 Boris Zbarsky 2013-10-23 06:33:25 UTC
So I've thought about this some more.

This bug's proposal (comment 0) comes down to making a whole bunch of methods that currently do not throw in certain cases start throwing in those cases.

Specifically, converting undefined to non-nullable interface arguments threw anyway.  But conversion to nullable interface arguments used to produce null and would now throw, and conversion to primitives used to produce 0/false/"undefined" (depending on the kind of primitive) and would now throw.

I strongly suspect that such a change is not web-compatible wholesale, which means that if we make it we will need to explicitly flag various APIs that are exceptions to the general rule for web compat purposes.  Coming up with such a list of APIs would be at best time-consuming and error-prone (in the sense of shipping browsers that break websites and finding out about that the hard way).

I do not expect Gecko to ship such a change before other UAs have done so and have submitted feedback on which APIs they had to munge for compat reasons (which is not a given, since other UAs seem to have a history of not submitting such feedback at all).  I strongly doubt any other UA vendors are any more willing than I am to stick their hands into this meat-grinder, but if they are they should of course speak up!

Another, perhaps less breakage-prone, way to get to the world proposed in comment 0 is to simply drop all arguments.length checks from WebIDL altogether and just blindly coerce things as needed.  So omitting a Node argument would still throw, but omitting a "Node?" argument would in fact act just like passing explicit undefined would.  A bunch of stuff like calling setAttribute() with only one argument (or no arguments, for that matter) which is currently specified to throw would stop throwing, which is a safer change to make than the reverse, albeit one that leads to less-debuggable code.  In this world, I'm not quite sure how overload resolution will work, but if this is the direction we want to go we can try to figure that out.  In some ways, overloaded methods that cannot be reexpressed in terms of unions are already so whack that it doesn't matter _that_ much how we resolve them.  :(

I should note that the "less breakage-prone" world is where WebKit and Blink already live, as far as I can tell.  Try http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2580 in Chrome or Safari.
Comment 13 Boris Zbarsky 2013-10-23 13:59:10 UTC
One more note: the change I describe sounds to me like putting theoretical purity ahead of web developers, since I suspect web developers would prefer a clear indication that a call like document.body.setAttribute() (with no arguments) is incorrect instead of it silently doing something bogus...  But that wouldn't be the first time, I guess; as far as I can tell we have a different priority of constituencies (though not spelled out) in TC39 than the WHATWG and HTMLWG generally seem to.
Comment 14 James Graham 2013-10-23 14:58:13 UTC
FWIW I would object to the change in Comment 12 for exactly the reason given in Comment 13; it makes the API more developer hostile but has few practical advantages. I also agree that the change suggested in Comment 0 is dangerous, but since there are people who seem to think that this consistency is important I hope they will do the work to discover the compatibility constraints.
Comment 15 Domenic Denicola 2013-10-23 15:08:53 UTC
>  since I suspect web developers would prefer a clear indication that a call like document.body.setAttribute() (with no arguments) is incorrect instead of it silently doing something bogus...

I don't think this is true, given the wide acceptance and prevalence of web developer-created libraries that do not do argument validation of this sort. (For example, jQuery.) Argument validation exceptions are not idiomatic to or expected by JavaScript code, generally. The only general case where I can recall developers writing them is for ensuring that properties of a configuration file necessary for app startup are present.

That said, even though I think it is a mistake to have these kind of argument validation exceptions, I can see that there are a number of people writing standards who are fond of them, so in the end it's unlikely that developers' desires are really what's going to decide the outcome here. With that in mind I think the original post describes the best way to express required arguments: if it's `undefined`, throw your `TypeError`.

Finally, I'd like to emphasize that `arguments`, and thus `arguments.length`, won't even be available inside any of ES6's new function forms, e.g. arrow functions, or any functions that use default arguments, rest parameters, or destructuring in their declaration. TC39 is trying as hard as possible to kill `arguments`.
Comment 16 Glenn Maynard 2013-10-23 15:19:19 UTC
(In reply to Domenic Denicola from comment #15)
> >  since I suspect web developers would prefer a clear indication that a call like document.body.setAttribute() (with no arguments) is incorrect instead of it silently doing something bogus...
> 
> I don't think this is true, given the wide acceptance and prevalence of web
> developer-created libraries that do not do argument validation of this sort.
> (For example, jQuery.) Argument validation exceptions are not idiomatic to
> or expected by JavaScript code, generally.

Of course we want to be told when we're doing something that is blatantly incorrect.  Libraries don't do it because it's cumbersome to do in JavaScript, but that's a bug, not a feature.
Comment 17 Erik Arvidsson 2013-10-23 15:55:08 UTC
I believe the rules in comment #0 are a bit too simplistic. For example passing undefined to a required boolean parameter needs to coerce it to false.

I believe the following rules would work.

1. Treat all nullable and boolean trailing parameters as optional. If there are optional parameters after a required parameter treat it as if it was optional.

  void foo(boolean b, optional T t)

would be treated as 

 void foo(optional boolean b = false, optional T t)

2. Treat all trailing nullable required parameters as optional, default to null.
3. For nullable required parameters treat undefined as null.
4. For boolean required parameters treat undefined as false.
5. For other required parameters, undefined and missing is an error.
6. For other optional parameters, undefined triggers the default

I think this can be simplified further but the main point is that we should be able to pass undefined to nullable and boolean parameters.
Comment 18 Allen Wirfs-Brock 2013-10-23 16:22:33 UTC
(In reply to Boris Zbarsky from comment #11)
> > Consensus was reached between representatives of all major implementors
> 
> With all due respect, the people representing SpiderMonkey there have
> nothing to do with the methods this bug is talking about changing.  In
> particular, they do not have any idea of what the compatibility constraints,
> if any, are.  So their consensus on the ES behavior doesn't mean much for
> the DOM, unfortunately.
> 

I don't think this is a fair statement WRT compatibility constrains. TC39 imposes severe compatibility constraints upon ourselves.  Our aspirational goal is to never break any existing JS code.  We would never change the language or the API of any ES built-in function in a way that would invalidate existing uses of the function. When we find this goal impossible to achieve  we are very careful to determine that any code that is broken is a extreme outlier.

From a TC39 perspective, we would say that, of course, you cannot invalidate any existing DOM API.

In Comment #12 you said,
>This bug's proposal (comment 0) comes down to making a whole bunch of methods
>that currently do not throw in certain cases start throwing in those cases.

If that's correct, it's absurd. There is no way that could actually happen to the web platform. 

There is nothing in ES6 that forces any changes to DOM APIs.   However, it will be good for the long term health of the platform, if DOM APIs began to look more like idiomatic JS APIs. The place to start is with new APIs.  My sense is that much of the difficulty you are encountering is that you are trying to apply a common set of conventions to both new APIs and your legacy APIs and this just doesn't work well because many of the legacy APIs do not follow idiomatic JS conventions.

What we do in TC39, in similar cases, is to simply bite the bullet and  describe the legacy API accurately but without using ES6 conveniences (such as default parameter values) that are inconsistent with the legacy. When all else fails we simply describe then as if the parameter signature was (...args) and provide an algorithic definition of the parameter processing.

Allen
Comment 19 Boris Zbarsky 2013-10-23 20:16:25 UTC
> With that in mind I think the original post describes the best way to express
> required arguments: if it's `undefined`, throw your `TypeError`.

My point is that I'll bet you $500 that doing this for setAttribute is not web-compatible.  Certainly not for the second argument.  I would be all in favor of doing this if it were not for this minor little detail.  Certainly if we were designing this as a green-field system we'd want to do that.

On the other hand, throwing if the argument is omitted altogether _is_ web-compatible.

> I believe the following rules would work.

Erik, I don't think these rules cover the setAttribute case at all.  Do you think you can compatibly change that case to throw if explicit undefined is passed?  If not, you need different rules.

> From a TC39 perspective, we would say that, of course, you cannot invalidate
> any existing DOM API.

Clearly at least Domenic disagrees...  but yes, that would be the sane approach to API design.

> The place to start is with new APIs.

That's not the proposal in this bug, sadly.  But yes, that would be much more palatable to me as an implementor.
Comment 20 Domenic Denicola 2013-10-23 20:33:55 UTC
> Clearly at least Domenic disagrees...  but yes, that would be the sane approach to API design.

I'm sorry if I've given any impression to the contrary. I thought we were discussing WebIDL rules, not what specific APIs should do. Specific APIs are constrained by web-compat; nobody is arguing that.

That said, we can still make fixes in the name of increased consistency where possible, and I'd argue that if setAttribute doesn't throw for undefined, it should not throw for missing argument. From what I can tell you believe this is still web compatible?
Comment 21 Jonas Sicking (Not reading bugmail) 2013-10-23 20:52:32 UTC
If the goal is "treat passing undefined the same as not passing the argument at all, even for non-optional arguments", then we actually have two options:

For a function like "void func(double arg)"

A) Make both func() and func(undefined) throw TypeError.
B) Make both func() and func(undefined) be equivalent to
   func(ToNumber(undefined)), i.e. equivalent to func(NaN).

So far we've mostly debated A, which doesn't seem very web compatible.

We certainly could do A for any new functions added to the platform, however that would create inconsistency between old and new functions which is unfortunate.

B is likely much more web compatible, and could probably be done for both old and new APIs. Not throwing also feels a lot more "javascripty", but that's obviously a matter of opinion.

I even *think* WebKit (and thus Blink) has done B for a long time.
Comment 22 Joshua Bell 2013-10-23 21:03:27 UTC
(In reply to Jonas Sicking from comment #21)
> For a function like "void func(double arg)"
> 
> A) Make both func() and func(undefined) throw TypeError.
> B) Make both func() and func(undefined) be equivalent to
>    func(ToNumber(undefined)), i.e. equivalent to func(NaN).
> 
> I even *think* WebKit (and thus Blink) has done B for a long time.

Assuming func is not overloaded, then in Blink (and WebKit last I knew) func() throws TypeError but func(undefined) coerces.
Comment 23 Allen Wirfs-Brock 2013-10-23 21:20:36 UTC
(In reply to Jonas Sicking from comment #21)
> If the goal is "treat passing undefined the same as not passing the argument
> at all, even for non-optional arguments", then we actually have two options:
> 
> For a function like "void func(double arg)"
> 
> A) Make both func() and func(undefined) throw TypeError.
> B) Make both func() and func(undefined) be equivalent to
>    func(ToNumber(undefined)), i.e. equivalent to func(NaN).
> 
> So far we've mostly debated A, which doesn't seem very web compatible.
> 
> We certainly could do A for any new functions added to the platform, however
> that would create inconsistency between old and new functions which is
> unfortunate.
> 
> B is likely much more web compatible, and could probably be done for both
> old and new APIs. Not throwing also feels a lot more "javascripty", but
> that's obviously a matter of opinion.
> 
and B is exactly how a JS function defined as
   function func(aNumber) { return +aNumber}

would behave if called either as func() or func(undefined)

It what a JS programmer expects, if leave out a argument that is used as a  number (or pass undefined) it will be treated as if it was NaN.
Comment 24 James Graham 2013-10-23 21:36:07 UTC
I am extremely skeptical of any claim that, given a function domFoo that takes a single non-optional, argument, js programmers benefit more from consistency between domFoo() and domFoo(undefined) than they do from throwing when the argument is missing. It seems far more likely to me that users missing non-optional arguments have made a mistake than that they are deliberately trying to invoke the effect of passing undefined, not least because the effect of passing undefined itself is often rather useless, and leads to a bad result (NaN, "undefined", null, etc.) which then propagates through the rest of the code making it extremely difficult to locate the original source of the bug.

Unless anyone has any concrete evidence that my suppositions above are incorrect, I oppose removing throwing behavior from legacy APIs and suggest throwing in both cases in future APIs.
Comment 25 Glenn Maynard 2013-10-23 21:45:25 UTC
It's certainly not what a JS programmer wants.  Having "Math.ceil()" return NaN instead of throwing an exception is useless, and does nothing but make development more difficult.

It may well not be web-compatible to throw in many cases (and that's ultimately what matters), but it's definitely better.  When it's this certain the programmer has made a mistake, tell them.
Comment 26 Jonas Sicking (Not reading bugmail) 2013-10-23 22:02:01 UTC
Though the same could probably be said for calling func(undefined). That seems likely to have happen due to code like

function doStuff(a) {
  ...
  func(a);
  ...
}
doStuff();

or

function doStuff(a) {
  ...
  func(a.value);
  ...
}
doStuff({ x: 12, y: 13 });


I can't say I have a strong opinion here. I still dislike the idea of having a split between old and new functions, but maybe it's better than the alternative.

One possible out would be to add warnings whenever undefined is passed to a required argument. And then slowly try to migrate old APIs to the new convention. But it sounds like bz's appetite is pretty low for that which I can understand given the amount of web-breaking experiments he's been through lately.
Comment 27 Boris Zbarsky 2013-10-24 00:27:01 UTC
(In reply to Domenic Denicola from comment #20)
> I thought we were discussing WebIDL rules, not what specific APIs should do.

If you change the meaning of a given string of WebIDL, that immediately changes all APIs that use that string of WebIDL.

The only options to not do that are to either make the new behavior uses a new syntax not used in current APIs or to go through all existing APIs and change them (or some subset of them, perhaps) to use some new syntax that opts out of the new behavior.

> That said, we can still make fixes in the name of increased consistency
> where possible, and I'd argue that if setAttribute doesn't throw for
> undefined, it should not throw for missing argument. From what I can tell
> you believe this is still web compatible?

It's web compatible.  I just think it's developer-hostile.

(In reply to Joshua Bell from comment #22)
> Assuming func is not overloaded, then in Blink (and WebKit last I knew)
> func() throws TypeError but func(undefined) coerces.

That's not the case in many cases.  See the simple testcase linked at the end of comment 12.

On the other hand, in Chrome document.querySelector() (with no arguments) does throw due to what looks like an arguments.length check.  But document.getElementById() (again, with no arguments) silently returns null.  So I can't tell when WebKit/Blink treat no argument as undefined and when they throw an exception.  Certainly it seems wholly uncorrelated with what any spec says right now.

(In reply to Jonas Sicking from comment #26)
> And then slowly try to migrate old APIs to the new convention.

In the long run that gives us a mix of APIs using the two conventions, I would expect...  Happy to see someone prove me wrong.
Comment 28 Allen Wirfs-Brock 2013-10-24 00:45:06 UTC
(In reply to Boris Zbarsky from comment #27)
...
> 
> (In reply to Jonas Sicking from comment #26)
> > And then slowly try to migrate old APIs to the new convention.
> 
> In the long run that gives us a mix of APIs using the two conventions, I
> would expect...  Happy to see someone prove me wrong.

No you're right.  But mixed conventions is already the reality for web developers who work a platform that includes the DOM APIs, the built-in JS APIs, and third party libraries that typically for the JS conventions. 

It will be better if new DOM APIs to follow the JS conventions, like everybody else.
Comment 29 Ms2ger 2013-10-24 07:27:43 UTC
If we want ES and DOM APIs to align, and the DOM APIs have clearly more useful behaviour, perhaps the ES APIs should change?
Comment 30 Erik Arvidsson 2013-10-24 14:03:33 UTC
(In reply to Ms2ger from comment #29)
> If we want ES and DOM APIs to align, and the DOM APIs have clearly more
> useful behaviour, perhaps the ES APIs should change?

There is one big difference between DOM APIs and JS. In JS you need to write functions that has optional parameters and calls other functions with optional parameters. In DOM you only need to call functions.

If you use arguments.length for these you have to do a lot of boiler plate code to cover all the options.

function g(x = undefined, y = undefined, z = undefined) {}

function f(x = undefined, y = undefined, z = undefined) {
  // do something
  switch (arguments.length) {
    case 0:
      return g();
    case 1:
      return g(x);
    case 2:
      return g(x, y);
    default:
      return g(x, y, z);
  }
}

But using the semantics in ES6

function f(x = undefined, y = undefined, z = undefined) {
  // do something
  return g(x, y, z);
}

Also, whether WebIDL has a more useful behavior is debatable. I haven't seen many (any?) JS libraries follow WebIDL.
Comment 31 James Graham 2013-10-24 14:23:07 UTC
(In reply to Erik Arvidsson from comment #30)
> Also, whether WebIDL has a more useful behavior is debatable. I haven't seen
> many (any?) JS libraries follow WebIDL.

That data would also fit the hypothesis that argument validation is too hard to do in JS and people are lazy so don't bother. Given that it is easy to make a case that throwing is preferable for API users but no one has even attempted to make a case, other than consistency, why not throwing might be preferable, I think my alternative hypothesis is significantly more likely.
Comment 32 Allen Wirfs-Brock 2013-10-24 17:37:21 UTC
(In reply to James Graham from comment #31)
> (In reply to Erik Arvidsson from comment #30)
> > Also, whether WebIDL has a more useful behavior is debatable. I haven't seen
> > many (any?) JS libraries follow WebIDL.
> 
> That data would also fit the hypothesis that argument validation is too hard
> to do in JS and people are lazy so don't bother. Given that it is easy to
> make a case that throwing is preferable for API users but no one has even
> attempted to make a case, other than consistency, why not throwing might be
> preferable, I think my alternative hypothesis is significantly more likely.

Step right up.  I've explained this many times to many people but will happily do it again.

Excess parameter validation is a well known anti-pattern among experienced dynamic language programmers. It results in code bloat and sometimes performance issues.

The code bloat is the occurrence of explicit "type" guards that occur over and over again in every functions. The majority of these are redundant and unnecessary because, if they really matter for safety (memory or operational), then the language guarantees the downstream primitive use of the value will perform the necessary safety checks.  

The performance issue, is that all of these checks are completely unnecessary, in a well tested  program. In such a program all values will validate correct, so they add nothing to the actual computational purpose of a function. Put a lot of these in a hot loop and you have a perf problem.

So when should a function (coded in a dynamic language) perform explicit parameter validation?  Only when the validation is necessary for maintaining essential invariants that the function is directly responsible for maintaining and even then only as a guard on the actual operations that are sensitive to the value.  Also, never explicitly validate something that is going to be validate by a primitive operation.

If you are just passing a parameter value on to another function, don't validate. The function you are calling should perform the validation if it is necessary for it to maintain its invariants. But more like than not, it also will just pass the value on and won't need to validate either.

So, aren't APIs special in ways that require that everything must be validate?  Sometimes, but certainly not always. (See http://www.wirfs-brock.com/allen/posts/379 for a deeper exploration of this question).  Many web platform APIs are just routine functions that are not special in any way and don't require any dynamic parameter validation.
Comment 33 Glenn Maynard 2013-10-24 17:57:02 UTC
Verifying the number of parameters is not "excess validation".  Verifying the number of parameters is a useful and well-understood part of modern dynamic languages.  See Python for a good example.

We can't get this everywhere in JavaScript due to heavy legacy constraints, but that doesn't mean we shouldn't have it at all.
Comment 34 Rick Waldron 2013-10-24 21:38:11 UTC
(In reply to Glenn Maynard from comment #33)
> Verifying the number of parameters is not "excess validation".  Verifying
> the number of parameters is a useful and well-understood part of modern
> dynamic languages.  See Python for a good example.

If a specific number of arguments is necessary for the given function to maintain its invariants, then the function should be defined with named formal parameters.


> 
> We can't get this everywhere in JavaScript due to heavy legacy constraints,
> but that doesn't mean we shouldn't have it at all.

There are no constraints described in your response.
Comment 35 Glenn Maynard 2013-10-24 22:08:33 UTC
(In reply to Rick Waldron from comment #34)
> (In reply to Glenn Maynard from comment #33)
> > Verifying the number of parameters is not "excess validation".  Verifying
> > the number of parameters is a useful and well-understood part of modern
> > dynamic languages.  See Python for a good example.
> 
> If a specific number of arguments is necessary for the given function to
> maintain its invariants, then the function should be defined with named
> formal parameters.

I can't tell what your reply has to do with what I wrote.  Named formal parameters are what we're discussing.  Please clarify.

> > We can't get this everywhere in JavaScript due to heavy legacy constraints,
> > but that doesn't mean we shouldn't have it at all.
> 
> There are no constraints described in your response.

There weren't intended to be.  Everybody reading this thread already knows that web compatibility is the legacy that constrains changing web APIs.
Comment 36 Rick Waldron 2013-10-25 14:09:34 UTC
(In reply to Glenn Maynard from comment #35)
> (In reply to Rick Waldron from comment #34)
> > (In reply to Glenn Maynard from comment #33)
> > > Verifying the number of parameters is not "excess validation".  Verifying
> > > the number of parameters is a useful and well-understood part of modern
> > > dynamic languages.  See Python for a good example.
> > 
> > If a specific number of arguments is necessary for the given function to
> > maintain its invariants, then the function should be defined with named
> > formal parameters.
> 
> I can't tell what your reply has to do with what I wrote.  Named formal
> parameters are what we're discussing.  Please clarify.

You said: 

> Verifying the number of parameters is not "excess validation".  Verifying
> the number of parameters is a useful and well-understood part of modern
> dynamic languages.  See Python for a good example.

Specifically: 

> Verifying the number of parameters

Which I assumed (maybe incorrectly) that you meant eg. defining conditional semantics of a function based on arguments.length. If that's what you meant, then I'm arguing this approach is brittle and error prone, versus defining conditional semantics by naming your parameters and observing their argument value.
Comment 37 Boris Zbarsky 2013-10-25 14:16:55 UTC
Rick, this bug is all about named formal parameters.  Checking their argument value for undefined and throwing if that's what was passed is almost not web-compatible in general.  That's what all the discussion is about!
Comment 38 Domenic Denicola 2016-10-21 21:29:35 UTC
I am pretty sure this is fixed for a couple years now, but someone should please reopen if I misunderstood.