Optional named parameters

Hello. I would like to propose the idea of optional named parameters for functions.

Motivation

As of now, developers have to remember and memorise the order of occurance function arguments to correctly use any function.
The other alternative is to pass objects, and one might easily pass in an object with a key value pair which the function does not need, or might mutate the values which should not be mutated.

Designing functions would also become easier since the developer has to worry less about order in which optional parameters are ordered from the left.

Proposal

I propose the language syntax and semantic to support optional named parameters. The following example should make it clear:

function greetPerson(first, last = '') {
  let message = `Hello, ${first}.`;
  if(last) {
    message+=` ${last}`;  
  }
  return message;
}

greetPerson('John', 'Doe') //? "Hello, John Doe"
greetPerson(last := 'Smith', first := 'Sam') //? "Hello, Sam Smith"

Other languages where this feature is available

This is a feature which is available in other programming languages like Python.

Rationale

This feature possesses the advantage of not worrying where the default parameter is mentioned in the function definition, for example: function person(first, last='', age) {...}.

I chose the above example because not all people have a last name. However, if one has to think of the possible applications, it can be quite useful: eliminating the need to memorise the order in which a function's parameters are defined.

One can clearly see the advantages of this when they are using a function which have more than a couple of parameters, as this does not warrant them to know the order of parameters. If they know the name of parameters, that should suffice.

Also, since it is optional, those who do not want to know the name of parameters and instead want to rely on the order of parameters, it works perfectly fine and is completely backwards compatible.

In case if a function has more than one parameters with default value, this feature also eliminates the overhead of thinking and evaluating which parameters the designer should put the rightmost, which one on the left.
For example: function personDetails(first, last='', age, children = []){...}.

Right now, the closest we have to this feature is to pass an object. That object can either be destructured in the function parameter, or later in the function definition.
However, often times the object can contain variables which the function does not need, and might mutate, which can be prevented if this feature were to exist.

To avoid that problem, one needs to create a new object, which might as well use named parameters. Another disadvantage of using the object as the parameter is unnecessary type declaration in another implementation of ECMAScript, namely TypeScript. And simpler parameters looks like an advandatge.

Without using the object, one can clearly see what are the parameters in a function, and use it directly, and also avoid unnecessary memorisation of the order of parameter.

I think "optional named parameters" is wonderful addition to the language. I welcome the opportunity to discuss about this idea.

Thank you for taking the time to read this proposal.

2 Likes

I don't think this change would be possible, since the syntax is already valid (assignment expressions):

let b;
console.log(b = 3); // 3
console.log(b);     // 3
1 Like

Updated the notation to:

greetPerson(last := 'Smith', first := 'Sam') //? "Hello, Sam Smith"

As is, this would make renaming a function argument a breaking change by default. I'd think we'd need to have a way for a function to opt itself in to this behavior - what would that look like?

I am not sure why this would be a breaking change. Perhaps I might be unsure of the mechanism to implement such design.

If that is the case, maybe we could make use of a keyword in front of the function, like how we have async, or symbol like * for generators, to distinguish the function.

What about enabling "call-by-object" notation instead:

Call-by-object is this:

func {  last : 'Smith', first : 'Sam'  };

and that is just a short form of

func ({  last : 'Smith', first : 'Sam'  });

where func is a function taking one argument.

Call-by-object notation is supported by script in Sciter, and example

1 Like

But would this be optional, and allow the default order as well?

Hello @acagastya,

Personally, I think this is unnecessary as we could just pass an object as the argument.

Example with default properties...

function plot({ x = 0, y = 0 }) {
  return y - x;
}
plot({ x: 1, y: 1 });

For JSDocs...

/**
 * @param {{ x: number, y: number }} coordinates
 * @returns {number}
 */
1 Like

I agree with @ethanlal04. I use destructuring + construction because it's clearer and order-independent. I think that's what you need, right?

const a = ({ x=0, y=0 }) => console.log( x,y );

a({ x:99 }); //> 99, 0
a({ y:99 }); //> 0, 99
a({ y:88, x:99 }); //> 99, 88
1 Like