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.go...@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. > >