"Exception: parameter(s) with default followed by parameter without default"

# David Bruant (13 years ago)

I've tried the following on Firefox:

function f(a, b = 34, c){ console.log('b', b) }

f(1, undefined, 43)

and got "Exception: parameter(s) with default followed by parameter without default" It seems intentional, but I wonder why it's been decided this way.

It seems that default values for parameters "in the middle" can be useful for older code base where parameters haven't been organized in prevision of default value without requiring a refactoring involving switching parameter order for all calls.

David

function f(a, b = 34, c){

console.log('b', b)

}

f(1, undefined, 43)

# Keith Cirkel (13 years ago)

You /are/ actually passing in a second argument though, your second argument is undefined. Default arguments aren't meant to replace undefined values, they're meant to be permissible for omission.

Keith Cirkel

# David Bruant (13 years ago)

2012/10/10 Keith Cirkel <es-discuss at keithcirkel.co.uk>

You /are/ actually passing in a second argument though, your second argument is undefined. Default arguments aren't meant to replace undefined values, they're meant to be permissible for omission.

From bugzilla.mozilla.org/show_bug.cgi?id=781422#c1 function f(x=EXPR) { BODY } will expand to: function f(x) { if (x === undefined) x = EXPR; BODY }

It seems that default arguments are meant to replace 'undefined' for last arguments and that's my experience playing with the latest nightly where the bug has been fixed.

What's the intention of the spec? Is current Firefox Nightly compliant? Can test262 tests be added to express what is expected from implementors? Debating tests would enable keeping track of the discussions that occurred and record the decision in an (arguably) more formal way than the spec.

# Allen Wirfs-Brock (13 years ago)

On Oct 10, 2012, at 6:19 AM, David Bruant wrote:

Hi,

I've tried the following on Firefox:

function f(a, b = 34, c){ console.log('b', b) }

f(1, undefined, 43)

and got "Exception: parameter(s) with default followed by parameter without default" It seems intentional, but I wonder why it's been decided this way.

That isn't a specified error and this function should be legal. For example, see the note in the definition of ExpectedArgumentCount in section 13.1 of the draft:

NOTE The ExpectedArgumentCount of a FormalParameterList is the number of FormalParameters to the left of either the rest parameter or the first FormalParameter with an Initialiser. A FormalParameter without an initializer is allowed after the first parameter with an initializer but such parameters are considered to be optional with undefined as their default value.

# Allen Wirfs-Brock (13 years ago)

On Oct 10, 2012, at 6:39 AM, David Bruant wrote:

2012/10/10 Keith Cirkel <es-discuss at keithcirkel.co.uk> You /are/ actually passing in a second argument though, your second argument is undefined. Default arguments aren't meant to replace undefined values, they're meant to be permissible for omission.

No, that isn't what the draft specification now says. It was originally that way, but TC39 based upon discussions here, decided that an explicit undefined argument value triggers default value initialization.

From bugzilla.mozilla.org/show_bug.cgi?id=781422#c1 function f(x=EXPR) { BODY } will expand to: function f(x) { if (x === undefined) x = EXPR; BODY }

It seems that default arguments are meant to replace 'undefined' for last arguments and that's my experience playing with the latest nightly where the bug has been fixed.

What's the intention of the spec? Is current Firefox Nightly compliant?

no

Can test262 tests be added to express what is expected from implementors? Debating tests would enable keeping track of the discussions that occurred and record the decision in an (arguably) more formal way than the spec.

Yes, if a contributor writes them. But the starting point for the tests need to be what the specification actually says.

# Oliver Hunt (13 years ago)

On Oct 10, 2012, at 9:12 AM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

On Oct 10, 2012, at 6:39 AM, David Bruant wrote:

2012/10/10 Keith Cirkel <es-discuss at keithcirkel.co.uk> You /are/ actually passing in a second argument though, your second argument is undefined. Default arguments aren't meant to replace undefined values, they're meant to be permissible for omission.

No, that isn't what the draft specification now says. It was originally that way, but TC39 based upon discussions here, decided that an explicit undefined argument value triggers default value initialization.

I still disagree with this decision, but from an implementation standpoint the cost difference is fairly minimal (there is of course an additional runtime performance cost, but i suspect it would be negligible).

I guess it depends on whether the committee feels that we should be encouraging the use of null over undefined in new syntactic constructs.

# Brendan Eich (13 years ago)

Oliver Hunt wrote:

On Oct 10, 2012, at 9:12 AM, Allen Wirfs-Brock <allen at wirfs-brock.com <mailto:allen at wirfs-brock.com>> wrote:

On Oct 10, 2012, at 6:39 AM, David Bruant wrote:

2012/10/10 Keith Cirkel <es-discuss at keithcirkel.co.uk <mailto:es-discuss at keithcirkel.co.uk>>

You /are/ actually passing in a second argument though, your
second argument is `undefined`. Default arguments aren't meant
to replace `undefined` values, they're meant to
be permissible for omission.

No, that isn't what the draft specification now says. It was originally that way, but TC39 based upon discussions here, decided that an explicit undefined argument value triggers default value initialization.

I still disagree with this decision, but from an implementation standpoint the cost difference is fairly minimal (there is of course an additional runtime performance cost, but i suspect it would be negligible).

The reason for treating undefined (and only undefined) as the sentinel value that triggers defaulting may not be clear to everyone. It is so that delegation layers do not have reproduce all the defaulting logic just to call the target function with the right number of parameters:

function foo(a, b, c) { log(stuff, a, b, c); return bar(a, b, c); } function bar(a = da, b = db, c = dc) { ... }

Without this, foo(1) and foo(2,3) calls would need to be special-cased in foo's body to call bar with only 1 or 2 arguments.

I guess it depends on whether the committee feels that we should be encouraging the use of null over undefined in new syntactic constructs.

What has null to do with your disagreement with there being a default sentinel? Or did you mean that you disagreed with only undefined being that sentinel?