Array patterns (and varargs patterns)

Swaranga Sarma sarma.swaranga at gmail.com
Mon Jan 11 00:29:01 UTC 2021


Thank you. I read the pattern matching doc (
https://github.com/openjdk/amber-docs/blob/master/site/design-notes/pattern-matching-for-java.md)
and although the example in the main is a little more complicated than the
one in the doc, I think I understand it now.

I recall in one of your earlier talks, (probably
https://www.youtube.com/watch?v=n3_8YcYKScw) you talked about how at
runtime, switch dispatch could be implemented as a decision tree with
constant time (O(1)) complexity. Is this still true with static patterns in
the mix? I think with static patterns since the method will need to be
executed, from the code author's perspective, it is no longer a constant
time evaluation - is that fair to say?

Regards
Swaranga


On Sun, Jan 10, 2021 at 11:50 AM Brian Goetz <brian.goetz at oracle.com> wrote:

>
> I am a little confused by the expression on the matcher, i.e the
> Integer.parseInt(var i) - it is not clear what is happening there and I
> don't think I have seen it before. Can someone explain what is being
> expressed by that case label?
>
>
> This is a _nested pattern_.  One of the powerful things about patterns is
> that they compose; when I say:
>
>     if (p instanceof Point(int x, int y)) { ... }
>
> the `int x` and `int y` that are the "arguments" of the deconstructor are
> actually _nested patterns_.  What this means is:
>
>    - test if p is a Point;
>    - if so, cast to Point, and invoke its (int, int) deconstruction
> pattern, which yields ints for the x and y components
>    - further match the resulting components to the patterns `int x` and
> `int y`, which happen to be total on `int`, and bind their target without
> reinterpretation.
>
> We can compose more interesting patterns.  Suppose I have a record
> Point(int x, int y) , and a record Circle(Point center, int radius).  Then
> I can match:
>
>     if (shape instanceof Circle(Point(var x, var y) p, int r)) { ... }
>
> This tests for circle-hood, extracts center and radius, and then further
> matches the center against Point(var x, var y), which happens to be total
> on Point.
>
> So the nested patterns inside the STring[] { ... } are matched against the
> elements of the array.  Now, what does `Integer.parseInt(var i)` mean?
> This is an example of a _static pattern_, which we don't have yet, but is
> part of the long-term story -- this is a (partial) pattern which applies to
> a String, which tries to parse the string as an int, and if so, binds the
> int.  In this way, we can compose the destructuring of the String array
> with the (possible) conversion from String to int, and either the whole
> thing matches (the thing is a string array, it has two elements, the first
> one can be parsed to an int, and we extract the int), or none of it does.
>
> Is it "match a String array with two elements the second of which is a
> valid Integer represented as a String value"?
>
>
> Yes :)
>
> The code for this pattern would live in Integer, as a declared pattern,
> when such a thing is supported.
>
> Cheers,
> -Brian
>
> Here is the snippet:
>
>     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); }
>
>     }
>
>  Regards
>
> Swaranga
>
>
> On Wed, Jan 6, 2021 at 8:44 AM Brian Goetz <brian.goetz at oracle.com> wrote:
>
>>
>>
>> > Other languages have patent matching on head and tail of lists. Adding
>> > this may mean there should be additional syntax.
>>
>> I alluded to this in my mail, hoping that people wouldn't allow
>> themselves to be distracted by this particular siren song:
>>
>> <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>
>>
>> The idiom of "match a list by matching (head, tail)", which works great
>> in Lisp and Haskell, is that (a) the representation of lists in Lisp and
>> Haskell is a cons-cell, and (b) these language have tail-call
>> elimination, so that processing a list by recursion in this manner is
>> natural, efficient, and doesn't SOE.  Java has neither of these, so
>> grafting the illusion of this model when the runtime is not suited to it
>> is just moving the problem one foot down the road, but ultimately is not
>> going to be satisfying.  The performance will be poor, and we'll SOE on
>> lists longer than a few tens of thousands of elements.
>>
>> The bottom line here is that idioms from Language X are very much
>> connected to _the rest of language X_.  Ignoring this rarely works out
>> well.
>>
>> > Another issue is if the array is shorter say 0 length and one has:
>> >
>> >        if (arr instanceof int[] { var a, var b, ... }) { ... }
>> >
>> > Will this be an ArrayIndexOutOfBoundException or another exception? If
>> > it is a reference type `a` and `b` can be null.
>>
>> No.  Pattern matching is inherently conditional; the match above says
>> "does `arr` match this array pattern".  Matching the array pattern means
>> being an array, _and_ having the right number of elements, _and_ having
>> those elements match the nested patterns. Matching should never throw
>> (though, once we allow users to write patterns that have code in them,
>> it will be possible to do things like NPE, but those are bugs.)
>>
>> >
>> >
>> > On Wed, 6 Jan 2021 at 15:31, Gavin Bierman <gavin.bierman at oracle.com
>> > <mailto:gavin.bierman at oracle.com>> wrote:
>> >
>> >     This is a feature that other languages call an “as pattern”,
>> >     because you are adding a new pattern variable binding to another
>> >     pattern (Standard ML used “as”, Haskell uses “@“ but calls it an
>> >     as pattern). It’s on our list of things to consider; part of the
>> >     consideration is whether it merits special syntax along with the
>> >     parsing issues of not having special syntax.
>> >
>> >     Gavin
>> >
>> >     > On 6 Jan 2021, at 05:44, Suminda Sirinath Salpitikorala
>> >     Dharmasena <sirinath1978m at gmail.com
>> >     <mailto:sirinath1978m at gmail.com>> wrote:
>> >     >
>> >     > Can we have something like:
>> >     >
>> >     >        if (arr instanceof String[] { var a, var b, ... }
>> >     stringArray) {
>> >     > ... }
>> >     >
>> >     > `stringArray` is optional but if present this will referrer to
>> >     the whole
>> >     > array.
>> >     >
>> >     >>
>> >
>>
>>
>


More information about the amber-dev mailing list