Array patterns (and varargs patterns)
Tagir Valeev
amaembo at gmail.com
Thu Jan 7 04:50:30 UTC 2021
Hello!
While I like the idea in general, what is annoying is the necessity to
repeat the expression type in every pattern:
switch (limitString.split(":")) {
case String[] { var _, Integer.parseInt(var i) } ->
setMultilineLimit(DEPTH, i);
case String[] { Integer.parseInt(var i) } ->
setMultilineLimit(LENGTH, i);
default -> { setMultilineLimit(DEPTH, -1);
setMultilineLimit(LENGTH, -1); }
}
Repetition of String[] looks noisy, and it doesn't add much
information for the code reader. I'm not sure what could be done here.
Probably a placeholder in the pattern to replace a selector type, like
this:
switch (limitString.split(":")) {
case _ { var _, Integer.parseInt(var i) } ->
setMultilineLimit(DEPTH, i);
case _ { Integer.parseInt(var i) } -> setMultilineLimit(LENGTH, i);
default -> { setMultilineLimit(DEPTH, -1);
setMultilineLimit(LENGTH, -1); }
}
But it looks ugly...
With best regards,
Tagir Valeev.
On Wed, Jan 6, 2021 at 1:48 AM Brian Goetz <brian.goetz at oracle.com> wrote:
>
> As we get into the next round of pattern matching, I'd like to opportunistically attach another sub-feature: array patterns. (This also bears on the question of "how would varargs patterns work", which I'll address below, though they might come later.)
>
> ## Array Patterns
>
> If we want to create a new array, we do so with an array construction expression:
>
> new String[] { "a", "b" }
>
> Since each form of aggregation should have its dual in destructuring, the natural way to represent an array pattern (h/t to AlanM for suggesting this) is:
>
> if (arr instanceof String[] { var a, var b }) { ... }
>
> Here, the applicability test is: "are you an instanceof of String[], with length = 2", and if so, we cast to String[], extract the two elements, and match them to the nested patterns `var a` and `var b`. This is the natural analogue of deconstruction patterns for arrays, complete with nesting.
>
> Since an array can have more elements, we likely need a way to say "length >= 2" rather than simply "length == 2". There are multiple syntactic ways to get there, for now I'm going to write
>
> if (arr instanceof String[] { var a, var b, ... })
>
> to indicate "more". The "..." matches zero or more elements and binds nothing.
>
> <digression>
> People are immediately going to ask "can I bind something to the remainder"; I think this is mostly an "attractive distraction", and would prefer to not have this dominate the discussion.
> </digression>
>
> Here's an example from the JDK that could use this effectively:
>
> String[] limits = limitString.split(":");
> try {
> switch (limits.length) {
> case 2: {
> if (!limits[1].equals("*"))
> setMultilineLimit(MultilineLimit.DEPTH, Integer.parseInt(limits[1]));
> }
> case 1: {
> if (!limits[0].equals("*"))
> setMultilineLimit(MultilineLimit.LENGTH, Integer.parseInt(limits[0]));
> }
> }
> }
> catch(NumberFormatException ex) {
> setMultilineLimit(MultilineLimit.DEPTH, -1);
> setMultilineLimit(MultilineLimit.LENGTH, -1);
> }
>
> becomes (eventually)
>
> switch (limitString.split(":")) {
> case String[] { var _, Integer.parseInt(var i) } -> setMultilineLimit(DEPTH, i);
> case String[] { Integer.parseInt(var i) } -> setMultilineLimit(LENGTH, i);
> default -> { setMultilineLimit(DEPTH, -1); setMultilineLimit(LENGTH, -1); }
> }
>
> Note how not only does this become more compact, but the unchecked "NumberFormatException" is folded into the match, rather than being a separate concern.
>
>
> ## Varargs patterns
>
> Having array patterns offers us a natural way to interpret deconstruction patterns for varargs records. Assume we have:
>
> void m(X... xs) { }
>
> Then a varargs invocation
>
> m(a, b, c)
>
> is really sugar for
>
> m(new X[] { a, b, c })
>
> So the dual of a varargs invocation, a varargs match, is really a match to an array pattern. So for a record
>
> record R(X... xs) { }
>
> a varargs match:
>
> case R(var a, var b, var c):
>
> is really sugar for an array match:
>
> case R(X[] { var a, var b, var c }):
>
> And similarly, we can use our "more arity" indicator:
>
> case R(var a, var b, var c, ...):
>
> to indicate that there are at least three elements.
>
>
More information about the amber-spec-experts
mailing list