New pattern matching doc

Alan Malloy amalloy at
Fri Jan 8 17:40:09 UTC 2021

Your example usage of an instance pattern surprised me a bit. You wrote:

On Fri, Jan 8, 2021 at 8:07 AM Brian Goetz <brian.goetz at> wrote:

>     case Foo f: // type pattern
>     case Foo(int x): // deconstruction pattern
>     case Foo.of(var x): // static pattern
>     case withMustard(var amount): // instance pattern
> For `case Foo f`, this is a type pattern, and the `Foo` class is
> uninvolved.  The applicability test is just classic `instanceof`.
> 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.
> 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.
> For `case withMustard(var amount)`, this is an instance pattern.  We look
> in the static type of `Foo` for an instance pattern called `withMustard`.
> The target becomes the receiver of the pattern invocation.

You say you look in the static type of Foo, but I think that isn't quite
what you meant: rather, we look in the type corresponding to whatever the
static type of the object being switched on is, which may or may not be Foo
(your example doesn't say). Otherwise, I don't see how we could possibly
come up with the type Foo specifically from this pattern-match use site.

But this left me with another question, going back to the notion of Map
having an instance pattern taking a key and binding a value. How do we
invoke that pattern, if we don't know whether the static type of the object
being matched is indeed Map? Say I am using a JSON decoder, and I want to
check several possibilities: if it's an int, do one thing; a list, do
another; a map containing a "type" key I will handle specially; and all
other maps should be handled in some default way.

Object o = JSON.decode(string);
switch (o) {
  case Integer x -> ...
  case List<Object> items -> ...
  case hasKey("type", String type) -> ...
  case Map m -> ...

if hasKey is an instance pattern, it seems I can't use it here. So, surely,
Map will want to define a static pattern with similar features, and then I
can write

  case Map.withKey("type", String type) -> ...

but then I ask, what is the point of the instance pattern, if the static
pattern accomplishes the same things, and all it "costs" is writing the
`Map.` prefix? I wouldn't expect Map to actually expose an instance pattern
at all, once it writes this static pattern that does the same thing. Do
instance patterns have some speicial privileges or something, that would
make using them more convenient in some situations, and outweigh the
inconvenience of needing to have the right static type already?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the amber-spec-experts mailing list