Let’s consider these statements:
Seq(1, 2, 3, 4).map(x => x + x * 2) // (1)
Seq(1, 2, 3, 4).reduce((x, y) = x*x + y*y) // (2)
Scala is ultimately expressive, but for case (1) some other languages provide better syntax, usually with a predefined name like it
:
Seq(1, 2, 3, 4).map(it + it * 2) // equivalent to (1)
At the same time in scala we may use shorthand syntax with positional arguments:
Seq(4, 5, 6, 7).map(_ * 2) // (3)
Seq(4, 5, 6, 7).reduce(_ - _) // (4)
Situations when we need to refer lambda argument more than once so we can’t use _
are very common. It would be great to have similar shorthand syntax in Scala.
It’s possible to introduce new syntax in line with tuple value accessors style:
Seq(4, 5, 6, 7).map(_1 + _1 * 2) // equivalent to (1)
Seq(4, 5, 6, 7).reduce( _1 * _1 + _2 * _2) // equivalent to (2)
Such a change should be relatively easy to implement and it should be pretty much safe for existing codebase.
In unlikely case of name conflict (someone has defined val _1 = 1
or imported tuple members) compiler may throw an error (preferred) or do shadowing + throw a warning. As well it’s possible to keep full backward compatibility by following simple rule: when you have lambda with arrow apply current logic, when lambda has no arrow shadow context with lambda named args.
In case people are happy with this idea I may come back with a patch.