0

JavaScript is the only language I've come aross which allows variable-length argument lists by default. A case where it would be helpful to detect too many arguments would be Mozilla's Add-On SDK's test cases.

To test whether two values are equal, you write

assert.equal(3, 4, "error message");

If you wanted to write equal, but instead chose the ok(truthVal, "message") function, you would test a truthy value like

assert.ok(3, 4, "error message");

and this test would pass. If the library would automatically check the number of arguments, (as f.ex. Python, Java, C, C++, ...), it could alert you to what is unexpected behavior 99% of the time.

  1. Why is this not done by default? Is there any use of default varags (in comparison to explicitly stating that a function takes a variable number of arguments)?

  2. Would it make sense to implement this in common libraries so that less users shoot themselves in the foot?

  • Since this is normal behavior for Javascript, how would the library check for too many arguments? – Robert Harvey Apr 27 '16 at 14:03
  • @RobertHarvey: By checking arguments.length > ... at invocation? – serv-inc Apr 27 '16 at 14:05
  • I see. And by "not done by default," are you referring to the writer of your hypothetical library, or by Javascript itself? – Robert Harvey Apr 27 '16 at 14:09
  • 2
    The answer to that question is "because that's how the designer designed the language," and today "because that's how it's always been done." Keep in mind that Javascript was designed in 10 days; for comparison, it took Rich Hickey 2 1/2 years to design Clojure. – Robert Harvey Apr 27 '16 at 14:19
  • 3
    This fellow recommends that you simply perform ordinary validation on the arguments that you do expect to get, which I agree with. Extra arguments are simply ignored by your function, so you don't have to do anything about those, unless you feel especially charitable. – Robert Harvey Apr 27 '16 at 14:36
2

Why is this not done by default?

For some reason, it wasn't done in the earliest versions of the language we now know as Javascript. Unfortunately, changing it now would break tons of existing code, so we're stuck with it.

Why not make this an "opt-in breakage" like strict mode? Probably because strict mode is focused on a small set of the most insidious kinds of errors caused by Javascript design flaws, such as x = 2 implicitly creating properties on the global object. Varargs-related bugs are annoying, but they were never close to being the most annoying part of the language.

Also because it's likely very hard to implement. Since functions are first-class values, there's nothing stopping you from replacing a two-argument function with a three-argument function at runtime. If we wanted the language to enforce the correct argument count at all call sites, it would have to start every function call start by asking the function how many arguments it currently takes. That's likely to be a performance problem, and it won't protect you from anything that you can't already protect yourself from.

Why was it like this in the early days? No idea. If I was to guess, I'd say because this reduces the number of things the interpreter has to keep track of.

Is there any use of default varags (in comparison to explicitly stating that a function takes a variable number of arguments)?

Even "default varargs" is understating it. All functions are variadic no matter what. You can't even opt out of it. You can only choose to throw an error at runtime if you don't like the arguments you were called with.

Since a lot less than 100% of real-world functions take a variable number of arguments, it's definitely a misfeature.

Would it make sense to implement this in common libraries so that less users shoot themselves in the foot?

If you're asking whether your assert library should be asserting its argument counts, that depends on a lot of things. But there's one in particular I think is worth pointing out in your example: assert.ok() could also catch that mistake by checking the types of the arguments it expects to get (i.e., the second argument should be a string), and that would probably lead to a better error message anyway.

I would generally prefer to focus on validating the arguments you are expecting to get. Explicitly checking the argument count too won't hurt, but it's definitely not necessary and probably never the top priority. If you have several arguments of the same type or potentially any type in a row, such that checking types alone won't detect this, that typically indicates a poorly-designed API rather than a need for argument count checking.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.