New pattern matching doc

Brian Goetz brian.goetz at
Mon Jan 11 15:38:31 UTC 2021

>         By example, case Optional.of() is called the static pattern in
>         the document, but the corresponding member is not static at
>         al, it has to have access to the values of the instance.
>     This is not correct.  The pattern `Optional.of()` is truly static. 
> The pattern is static, but perhaps not as "static" in a static method 
> call, but as "static" in a method reference way.
> For Optional.of(var x), the implementation needs to take a look to the 
> content of the Optional, thus the implementation is not static as in 
> static method.

For static patterns, the target is passed as an argument.  Just like the 
following method:

     class Foo {
         static<T> T unboxIfPresentOrNullIfAbsent(Optional<T> target) {
             return target.isPresent() ? target.get() : null;

This is a static method that "matches" present optionals, and returns 
their contents if present, or a sentinel if not.  The static pattern 
Optional::of does the same, just not as a method.

> For Integer.parseInt(int value), this is not a instance method of 
> String but a static method inside Integer that either binds an int or 
> does not match.

There's no conceptual difference between this and Optional::of. Each are 
passed the target; in the former case, the target is an Optional, in the 
latter, its a String.

>     For `case Foo(int x)`, this is a deconstruction pattern, and Foo
>     is the name of a class, not of a pattern.  Just like with
>     constructors, we look in class Foo (not superclasses) for a
>     matching deconstructor.  The target becomes the receiver of the
>     pattern invocation. 
> The application test is an instanceof + a call to the deconstructor 
> which as a special linking semantics for transferring the bindings

I am not sure I like the word "call" here, as it suggests that you are 
trying to cast these things as methods. Under the hood, of course there 
are going to be methods, because that's what the JVM offers us.  But 
we're talking about the language model here, so I'd like to avoid 
confusing words.   But yes, it is as if we are "calling" the 
deconstructor which puts the bindings somewhere the "caller" can get them.

>     For `case Foo.of(var x)`, this is a static pattern.  Foo is the
>     name of a class, and `of` is the name of a declared static pattern
>     in Foo.  The target becomes an argument of the pattern invocation. 
> The application test is an instanceof + a call to the method an 
> instance method of() with, i hope, the same special semantics for 
> transferring the bindings.

Same transfer of the bindings, but it is not an instance method; static 
patterns translate to static artifacts.  The switch target (the Foo) is 
passed as an ordinary parameter.  Then, there is an additional wrinkle 
on the bindings transfer, because the pattern might say "nope, not 
really a Foo of anything", in which case we "transfer" a sentinal that 
says "these bindings are no good, don't use them."

> Unlike the deconstructor, this instance method can be overridden (you 
> want to be able to declare such method on an interface).

No, but instance patterns can.

> It's more that i want that all patterns that have bindings to share 
> the same meta-protocol (the way to bind bindings).

That is how this works.  Here's the full (abstract) protocol.

  - Every pattern has a target, which is "passed" from the client to the 
  - Every pattern can have zero or more output bindings, which are 
"passed" back from the pattern to the client.
  - Patterns can succeed or fail.  In case of failure, they return no 
  - Some patterns are constrained to never fail (total patterns.)
  - Patterns may take additional (input) arguments.  (Canonical example: 
a "regex" pattern that takes the regex pattern as well as the target.)

Different patterns use different subsets of this protocol.  Total 
patterns don't make use of the "might fail" channel; none of the 
patterns so far make use of the "extra args" channel.

This maps to instance/static in a straightforward way: for instance 
patterns, the target is the receiver, for static patterns, it is passed 
as the first input argument.

> But a constructor neither need a special keyword nor have a semantics 
> different from a classical methods

But this is just not true!  Constructors are different in both syntax 
and semantics from classical methods.

If I had to read between these pages of indirect objections, I'm tempted 
to guess that this is all really just: "I'm disappointed that we didn't 
make constructors just be static methods in the first place, and I want 
to fix that mistake now?"

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the amber-spec-experts mailing list