Named Paramters

# Benjamin Gruenbaum (5 years ago)

Hey, I wasn't able to find information about the current status of a named parameters propsosal:

// as in:
foo(bar = 5); // logs 5

function foo(baz, bak, bar){
     console.log(bar);
}

Is this being considered? Was it decided for/against? Anyone working on it?

# Bucaran (5 years ago)

What about:

foo({ bar: 5 })

function foo ({ baz, bak, bar }) {
	console.log(bar)
}

Or is there anything else you are considering or something I am missing.

# Gary Guo (5 years ago)

If we really need this, you may want to use colon to replace the assignment operator in your example. foo(bar: 5)

# Benjamin Gruenbaum (5 years ago)

No, I didn't mean simulating them via an object literal. I mean actual named parameters like in Python or C# for example.

Are there any plans to peruse that and if so what is the status?

# Denis Pushkarev (5 years ago)
  1. It would break backwards compatibility:
var bar = 1;
if(baz(bar))foo(bar = 5);
console.log(bar); // 5 in some cases
  1. Code with this feature will be broken after minification.
# Peter van der Zee (5 years ago)

(A minifier that breaks your code is a broken minifier and should never be a valid argument for these cases)

# Gil Tayar (5 years ago)

It won't break if Gary Guo's idea is used, i.e. use a colon instead of an equal.

# Denis Pushkarev (5 years ago)

So you propose don't compress arguments of all functions? :)

# Benjamin Gruenbaum (5 years ago)

I think my original post might have been confusing so allow me to clarify.

I'm not suggesting to add named parameters to the language, I did not intend to start a discussion about named parameters' merits vs passing an object literal (I thing Axel had a blog about that a while ago).

What I'm interested in is *where the **is *TC standing in this regard.

  • Are there any proposals currently under work (TC's GitHub suggests no)?
  • Were there proposals in the past that were rejected or abandoned?
  • Was there discussion about named parameters in the language before?

Since I sent the original email I've found lukescott/es-named-arguments which isn't a proposal yet but looks pretty new, so I'll just cc Luke and see if he can update us all (although it looks like his proposal ties it to type hints) :)

# Luke Scott (5 years ago)

On Jul 12, 2015, at 2:48 AM, Benjamin Gruenbaum <benjamingr at gmail.com<mailto:benjamingr at gmail.com>> wrote:

I think my original post might have been confusing so allow me to clarify.

I'm not suggesting to add named parameters to the language, I did not intend to start a discussion about named parameters' merits vs passing an object literal (I thing Axel had a blog about that a while ago).

What I'm interested in is where the is TC standing in this regard.

  • Are there any proposals currently under work (TC's GitHub suggests no)?
  • Were there proposals in the past that were rejected or abandoned?
  • Was there discussion about named parameters in the language before?

Since I sent the original email I've found lukescott/es-named-arguments which isn't a proposal yet but looks pretty new, so I'll just cc Luke and see if he can update us all (although it looks like his proposal ties it to type hints) :)

At the moment my focus has been on type hints, although I've been rather busy at work. I have a few tasks to finish on that :).

The named parameters example is one rational why a space should be used for type hints instead of a colon. I had brought up named parameters on the list at some point and some people suggested destructuring instead. Personally I'd rather be able to name parameters without creating an object.

The status of the repo is it's currently a concept.

Luke

# Benjamin Gruenbaum (5 years ago)

Thanks for the clarification.

# Allen Wirfs-Brock (5 years ago)

On Jul 12, 2015, at 1:48 AM, Benjamin Gruenbaum wrote:

I think my original post might have been confusing so allow me to clarify.

I'm not suggesting to add named parameters to the language, I did not intend to start a discussion about named parameters' merits vs passing an object literal (I thing Axel had a blog about that a while ago).

What I'm interested in is where the is TC standing in this regard.

  • Are there any proposals currently under work (TC's GitHub suggests no)?

not with TC39, AFAIK

  • Were there proposals in the past that were rejected or abandoned?

probably (and informally) but you'd have to search the last 10 years of es-discuss and TC39 meeting notes

  • Was there discussion about named parameters in the language before?

Yes, when object destructuring of function parameters was first being discussed. The TC39 consensus was that the option object pattern had already adequately filled that ecological niche so we focused on making sure that parameter destructuring were useful for dealing with them.

# Benjamin Gruenbaum (5 years ago)

Ok, thanks, that clarifies it.

# Alexander Kit (5 years ago)

This is extremely for the optional parameters important

function foo (bar, bak=1, qux=2) { }

// here I want bar to be default, but the quux take another value foo(5, qux: 3);

People often suggest object destruction here, but it is then just a workaround. And when the arguments are renamed during the minification, all the labels in function calls can be minified accordingly too.

# Michał Wadas (5 years ago)

In fact, it's impossible.

And when the arguments are renamed during the minification, all the labels in function calls can be minified accordingly too.

You can't statically determine which function will be called. Minifier CAN'T know in general case if your $(selector='wow') calls jQuery or some other function at minify time.

So: you can't rely on optional parameters in any CDN-distributed file (because your minifier doesn't know about it's pre-minification identifiers), minifier have to avoid any parameters names clash at any cost.

Possible solution: add gramar explicitly declare optional parameters by keyword to avoid minifaction of their names names.

# Benjamin Gruenbaum (5 years ago)

If we wanted to add named parameters, we would probably have a different name for the named parameter inside the function and outside the function.

function foo(x as y){

}

foo(y = 5);

Or something like that. That said, I'm not convinced we need named parameters, that they justify the additional cost or the overhead, that current solutions like destructing aren't enough and so on. Even if we all agreed that we want named parameters, and we agreed in general lines how it should be done, and we convinced the TC, there would still be a lot of work to actually "decide' they should make it to ES.

So I suggest we close this thread and anyone who feel strongly about including named parameters should work on a concrete proposal :)

# Alexander Kit (5 years ago)

Seems everybody is pessimistic about this. But using optional labels would solve any problem with the minifiers.

// Not minified (Labels are optional, default are the variable names)
function foo (bar = 1, baz = 2, bak = 3) {
console.log(baz);
}
foo (baz: 2);

// Minified
function foo(bar:a=1,baz:b=2,bak:c=3){console.log(b)}
foo(baz:2);

// Explicit Label
function foo (bar = 1, baz: myVar = 2, bak = 3) {
console.log(myVar);
}
foo (baz: 2);

// Minified (same)
function foo(bar:a=1,baz:b=2,bak:c=3){console.log(b)}
foo(baz:2);

And when talking about static analysis, then it is really not always possible to determine the global function variables, but within the scope(s) it shouldn't be the problem. But anyway, the labels will cover all the cases.

Sorry for bothering, if I miss something, Alex

# Bradley Meck (5 years ago)

There are a couple of people tossing around named parameter ideas that have different identifiers than the argument identifier. What is wrong with what Gary Guo originally said with foo(bar: 5), it uses : for mapping similar to an object literal, but does not require having contextual knowledge and breaking changes like = would; it also does not require having multiple identifiers for the same variable.

Perhaps I may be wrong here, but having multiple identifiers/bindings to the same variable seems fraught with confusion.

# Axel Rauschmayer (5 years ago)

On 12 Jul 2015, at 16:05, Luke Scott <luke at webconnex.com> wrote:

Personally I'd rather be able to name parameters without creating an object.

The intermediate object seem like something that JavaScript engines could eliminate by statically analyzing the code. I’m wondering whether any engine is planning to do that.

# Michał Wadas (5 years ago)

Proposal that do not conflict with minimifiers:

  • Functions have optional named parameters in any place of argument definition. Optionality is defined by presence of hash character at beginning of parameter name. Optional parameters CAN be placed after rest parameter. These parameters can be accessed by name or by position:
function foo(bar, #qaz, boo) {
return [bar, qaz, boo];
}
foo(1,2,3); // [1,2,3]
foo(#qaz: 3, 4, 1); // [4,3,1] or [4,1,undefined] or throw?

function faz(bar, ...baz, #qoo) {
return [bar, ...baz, qoo];
}
faz(1,2,3,4,#qoo:5); // [1,2,3,4,5]

function print(...toPrint, #delimiter=',', newLine='\n') {
console.log(toPrint.join(delimiter)+newLine);
}
let delimiter = ':';
print(1, 2, 3, 4, 5,#{delimiter}); // prints '1:2:3:4:5\n'

Possible solutions for nonexistant optional argument (eg. foo(#nope:null) ):

  • throw (probably the worst solution )
  • define arguments[Symbol.optionals] object (great for passing optional arguments)
  • allow syntax for "rest optional parameters"
  • ignore

Some problems:

  • probably this syntax can not be transpiled in general case
  • there is no intuitive behavior for print (1,2, #delimiter:' ', #{delimiter})
  • how will .apply work? Third argument with optional arguments? Symbol.optionals property on second argument (good for seaminglessly passing arguments, but it doesn't sound like good idea for arrays)?.

Any thoughts?

# Soni L. (5 years ago)

Could add f{} as sugar for f({}), and make engines optimize f{}? (no positional arguments though)

# joe (5 years ago)

In principle, I agree with Bucara re: the ({}) syntax. Unfortunately this is often too slow to use in practice. Everyone keeps hoping browser vendors will come up with a way to optimize out small object allocations, but I think that's a pipe dream, because we do have a language that handles fine-grained allocation well: Python.

Python combines reference counting with a cyclic garbage collector. This allows it to amortize the GC cost; most objects (especially small use cases like this one) are destroyed by reference counting. There is, however, a downside: speed. In the case of JS, if one is careful, makes use of object caches and thus manually controls his memory use, one can virtually eliminate the overhead from traditional collectors. One cannot avoid the overhead from reference counting in Python, however.

Collecting many small, heap-allocated objects is just a hard problem to solve, and will always have costs. In the end, I think we will have to find some way for garbage-collected languages to accommodate some sort of stack allocation. There are languages that experiment with them (one of my old college professors wrote a really cool one), but the idea is still relatively undeveloped.

Joe

# Soni L. (5 years ago)

Engines could inline and infer lifetimes, use stack allocation when possible, etc. Kinda like how LuaJIT is so fast.

Just because they don't yet doesn't mean we should hold back features which would work better if they did.

Plus, you don't /need/ to use "garbage collectible objects" for it. In theory (and in practice) your internal bytecode could have something like this:

function f(x) { return x.y; }

FUNCTION "f" ARG "x" NOGC ; = basically doesn't have to be a "GC object" RET x.y

f({y=3})

SET (temp1) {y=3} NOGC CALL "f" (temp1) FREE (temp1)

You know f takes a NOGC argument, you can create a NOGC object. You could even inline both the call and the object access, actually.