Syntax Proposal: Anonymous Arguments

# Kenneth Powers (8 years ago)

I have a proposal for new syntax in ES inspired by the placeholder syntax in Scala Functions docs.scala-lang.org/overviews/quasiquotes/expression-details.html#function .

Essentially, the idea would be to allow anonymous arguments. The most simple example would be a function which takes one argument (as far as the programmer is concerned):

[1, 2, 3].map(@ + 1)

This would be the same thing as:

[1, 2, 3].map(n => n + 1)

Just like in Scala, an anonymous function is created. This concept can be further extended in ES:

[1, 2, 3].reduce(@0 + @1, 0)

Which would be the same thing as:

[1, 2, 3].reduce((sum, n) => sum + n, 0)

Thoughts?

# Jordan Harband (8 years ago)

In Scala, the ambiguity of the underscore causes lots of confusion when you have nested functions - how is that handled in your proposal?

Bear in mind, I think it's a tough argument that @ + 1 is so much better than n => n + 1 that it warrants its own syntax.

Separately, the "@" is reserved for an existing proposal, so you'd have to come up with different syntax anyways.

# Kenneth Powers (8 years ago)

What proposal is "@" reserved for, by chance? I was trying to pick something that both wasn't used and can't be the name of a variable (e.g., underscore). I saw another proposal for "?" for partially applying functions, but that would be potentially ambiguous with the ternary operator.

As for resolving ambiguity, why not just do what Scala does stackoverflow.com/questions/19916169/scala-arguments-of-nested-lambdas-with-short-syntax/19917720?

It would seem to me that nesting these functions would be a sign you need to refactor anyway.

As far as meriting its own syntax, that's why I referenced another language where the implementors found that it did merit its own syntax (though the underscore in Scala also does a lot more).

# Jordan Harband (8 years ago)

@ is currently reserved for decorators, # currently for private fields. There aren't a lot of compelling syntax options left, to be sure.

# Rick Waldron (8 years ago)

What does this mean:

let f = @;

# doodad-js Admin (8 years ago)

Should not “private fields” be a decorator ?

From: Jordan Harband [mailto:ljharb at gmail.com] Sent: Friday, September 23, 2016 4:32 PM To: Kenneth Powers <ken at kenpowers.net>

Cc: es-discuss <es-discuss at mozilla.org>

Subject: Re: Syntax Proposal: Anonymous Arguments

@ is currently reserved for decorators, # currently for private fields. There aren't a lot of compelling syntax options left, to be sure.

On Fri, Sep 23, 2016 at 11:35 AM, Kenneth Powers <ken at kenpowers.net <mailto:ken at kenpowers.net> > wrote:

What proposal is "@" reserved for, by chance? I was trying to pick something that both wasn't used and can't be the name of a variable (e.g., underscore). I saw another proposal for "?" for partially applying functions, but that would be potentially ambiguous with the ternary operator.

As for resolving ambiguity, why not just do what Scala does stackoverflow.com/questions/19916169/scala-arguments-of-nested-lambdas-with-short-syntax/19917720 ? It would seem to me that nesting these functions would be a sign you need to refactor anyway.

As far as meriting its own syntax, that's why I referenced another language where the implementors found that it did merit its own syntax (though the underscore in Scala also does a lot more).

On Fri, Sep 23, 2016 at 2:00 PM, Jordan Harband <ljharb at gmail.com <mailto:ljharb at gmail.com> > wrote:

In Scala, the ambiguity of the underscore causes lots of confusion when you have nested functions - how is that handled in your proposal?

Bear in mind, I think it's a tough argument that @ + 1 is so much better than n => n + 1 that it warrants its own syntax.

Separately, the "@" is reserved for an existing proposal, so you'd have to come up with different syntax anyways.

On Fri, Sep 23, 2016 at 10:38 AM, Kenneth Powers <ken at kenpowers.net <mailto:ken at kenpowers.net> > wrote:

I have a proposal for new syntax in ES inspired by the placeholder syntax in Scala Functions docs.scala-lang.org/overviews/quasiquotes/expression-details.html#function .

Essentially, the idea would be to allow anonymous arguments. The most simple example would be a function which takes one argument (as far as the programmer is concerned):

[1, 2, 3].map(@ + 1)

This would be the same thing as:

[1, 2, 3].map(n => n + 1)

Just like in Scala, an anonymous function is created. This concept can be further extended in ES:

[1, 2, 3].reduce(@0 + @1, 0)

Which would be the same thing as:

[1, 2, 3].reduce((sum, n) => sum + n, 0)

Thoughts?

# Alan Johnson (8 years ago)

I found the underscores in Scala confusing at first, for sure. Of course, after a couple months working with the language, you feel right at home.

Worth noting that Swift does something kind of like Bash, with indexed shorthand argument names developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html, which lets you can reuse your anonymous argument. It comes in handy when you don’t want to clutter code with names for things that are obvious. But I think it only works within curly braces.

Obviously, both variations require judgment of knowing when the meaning of the argument is self-evident.

# Kenneth Powers (8 years ago)

Of course, decorators. # was actually my original idea when I was discussing this with co-workers. One of them suggested <>, which reminds me of the multi-character proposal for pipelining (|>, I believe). In the case of indexed shorthand argument names as in my original proposal (and bash, and swift) something like <0>, <1>, <2>, etc may work.

I also got this directly in my inbox (I think he forgot to reply-all):

Might be interesting if it included template strings...

return weeks.map(Week ${@ + 1});

I think template strings are a really interesting side effect of this proposal (shouldn't require any additions to the actual proposal), even without inline operations. Consider:

people.map(`Name: ${<>}`);

Which desugars to:

people.map(name => `Name: ${name}`);
# Bob Myers (8 years ago)

How would I write

a => b => a + b

I could write

a => a + @

but that only gets me half-way.

# Claude Pache (8 years ago)

Le 23 sept. 2016 à 20:35, Kenneth Powers <ken at kenpowers.net> a écrit :

As for resolving ambiguity, why not just do what Scala does stackoverflow.com/questions/19916169/scala-arguments-of-nested-lambdas-with-short-syntax/19917720? It would seem to me that nesting these functions would be a sign you need to refactor anyway.

Concretely, when you write:

listOfNumbers.map(Math.floor(@) + 1)

what does it mean:

_ => listOfNumbers.map(Math.floor(_) + 1) // (1)

listOfNumbers.map(_ => Math.floor(_) + 1) // (2)

listOfNumbers.map(Math.floor(_ => _) + 1) // (3)

? Although the most reasonable interpretation for a human would be (2), because the parser is unable to read your mind or to make a qualitative distinction between listOfNumbers.map and Math.floor (both are just functions), it will most probably misinterpret it as (3).

That syntax looks like an attractive nuisance to me.

# Isiah Meadows (8 years ago)

I agree. Also, in particular, Scala's partial application syntax does tend to confuse newcomers, and can easily border on the same obfuscation level as point free style in Haskell for similar reasons (which is easier to understand, owl = (.) . (.) or owl f g x y = f (g x y)). Also, I'm not sure such syntax is actually necessary. If anything, curried operator functions like what Python has (the operator module), but hopefully more concise, would completely solve most of this, and could probably start as an easy trivial userland library. (Note that Lodash and Underscore both already provide some of these uncurried.)

# Tab Atkins Jr. (8 years ago)

On Fri, Sep 23, 2016 at 10:38 AM, Kenneth Powers <ken at kenpowers.net> wrote:

I have a proposal for new syntax in ES inspired by the placeholder syntax in Scala Functions.

Essentially, the idea would be to allow anonymous arguments. The most simple example would be a function which takes one argument (as far as the programmer is concerned):

[1, 2, 3].map(@ + 1)

This would be the same thing as:

[1, 2, 3].map(n => n + 1)

Just like in Scala, an anonymous function is created. This concept can be further extended in ES:

[1, 2, 3].reduce(@0 + @1, 0)

Which would be the same thing as:

[1, 2, 3].reduce((sum, n) => sum + n, 0)

Thoughts?

While I like really concise callbacks for simple cases like this, the win over arrow functions is so tiny here. map(@+1) vs map(x=>x+1)

is 3 characters different; map(@0+ at 1) vs map((x,y)=>x+y) is 5.

Having to learn a new syntax for tiny functions that only gains an extremely miniscule benefit in terms of code size is an extremely hard sell.

Compound this with the fact that the @ glyph is already spoken for, and you have an extreme uphill battle to deal with.

I suggest just living with the few extra characters that arrow functions impose, and being happy we no longer have to type out "function ... { return }". ^_^