I"m not sure if a separate unapplyNamed
method would be good idea. When we want to allow mixed usage, like Foo(1, x = 2)
, both the positional and the named pattern should be handled by the same unapply
. To avoid clashes with preexisting methods, maybe the names should be prefixed with underscore e.g. _city
, just like _1
.
Following the example of the specs, I’d like to propose very boldly:
class FirstChars(s: String):
def _1 = s.charAt(0)
def _first = _1
def _2 = s.charAt(1)
def _second = _2
def _get(i: Int) = if i < s.length then Some(s(i)) else None
def isEmpty = false
def get = this
object FirstChars:
def unapply(s: String): FirstChars = new FirstChars(s)
"Hi!" match
case FirstChars(char1, char2 = second, char2 <- 3) =>
println(s"First: $char1; Second: $char2; Third: $char3")
The rules for patterns become:
-
<pattern>
at positionn
resolves to a pattern on_<n>
, just like before -
<pattern>
=<name>
resolves to a pattern for the field_<name>
.
Important: I swapped the position of name and pattern, in comparison the my previous proposal. This seems counter intuitive, as destroys the perfect alignment with the constructor. But in Scala an equal sign always meas set the (new) name left of the sign to the result of the expression right of sign. It also avoids a look-ahead in the parser.
Notice than the restriction to only allow names is arbitrary. It’s only there to prevent people to shot in there own foot. -
<pattern>
←<expr>
resolves to a pattern for_get(<expr>)
This is a new capability and could be left out. But it shows the similarity to for-comprehensions.
I’ll try try to update the prototype and the proposal, but maybe this is more than I can chew.