Syntax Proposal: Anonymous Arguments
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.
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).
@ is currently reserved for decorators, # currently for private fields. There aren't a lot of compelling syntax options left, to be sure.
What does this mean:
let f = @;
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?
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.
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}`);
How would I write
a => b => a + b
I could write
a => a + @
but that only gets me half-way.
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.
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.)
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 }". ^_^
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):
This would be the same thing as:
Just like in Scala, an anonymous function is created. This concept can be further extended in ES:
Which would be the same thing as:
[1, 2, 3].reduce((sum, n) => sum + n, 0)
Thoughts?