Compact deconstruction patterns

Remi Forax forax at
Wed Mar 4 10:18:07 UTC 2020

I think Brian is miles ahead :)
that's why you did not understand his answer, let me try to explain the problem and why var/type is the best choice.

Let's takes an example, using the syntax you propose,
var shape = ...
var value = switch(shape) {
  case Point(x, y) -> x + y;

now we also want to support adding constant as pattern,
something like
var value = switch(shape) {
  case Point(0, y) -> y;

obviously, if we support constant, we also need to support variable,
so the last code can be rewritten like this by introducing a new local variable x
var x = 0;
var value = switch(shape) {
  case Point(x, y) -> y;

And here, i'm sure you have spot the issue, 'case Point(x, y)' is now ambiguous, because whe don't know if x refer to the local variable above or to a fresh new local variable.

If you study other languages that have pattern matching, there are 3 possible solutions
  1. be clever but ...
  2. use a pin operator
  3. use var

Option 1, we can be clever, in Java, you can not introduce the same local variable twice so 'case Point(x, y)' means that x is the already existing local variable because otherwise, introducing a new fresh local variable will result in an error. But this solution has two drawbacks, the most important, it means that introducing a local variable above a switch (or an instanceof, etc) change the semantics of the switch, not a good property apart if you write code puzzler for a living. The other issue is that it interacts badly with fields. By example, if you have the code
  class Foo {
    int x;
    void m() {
      var value = switch(shape) {
        case Point(x, y) -> y;
here 'x' in case Point(x, y) means it's a fresh variable, if you want to use the field, you have to explicitly prefix it by 'this' (or the class for static field). If Java was not Java but Ruby (that has a different syntax for field and local variable), it may have been a good solution, but the fact that you can reference a field or a local variable using the same syntax in Java makes the option 1 not a good fit for Java.

Option 2, like in Elixir, we have a special syntax to denote that a name inside a pattern is an existing local variable and not a fresh local variable.
Elixir uses the operator ^ for that.
var x = 0;
var value = switch(shape) {
  case Point(^x, y) -> y;
In Elixir, you declare a local variable like this "x = ..." like in Python, there is no prefix keyword let/var like in Java, JavaScript. So for Elixir, it makes sense to reuse the same syntax to create a fresh variable and to use a special syntax if you want to reference a local variable.
But in Java, you declare a new local variable by prefixing it with a type or var, so using a pin operator whatever the syntax will be alien to the rest of the Java code.

So Option 3, use var and the type everywhere you want to have a fresh local variable. It's stupid because in most of the cases, you want more a fresh new local variable than an existing local variable but it fits with the other constructs of the language and readability and consistence have always been more important that the number of characters in Java.

I hope this help !


----- Mail original -----
> De: "Brian Goetz" <brian.goetz at>
> À: "Tagir Valeev" <amaembo at>
> Cc: "amber-dev" <amber-dev at>, "Matthias Perktold" <tias251 at>
> Envoyé: Mercredi 4 Mars 2020 08:55:19
> Objet: Re: Compact deconstruction patterns

> That’s all fine, but I think you are mischaracterizing the reason we are
> preferring var?  t’s not because we don’t like the alternative. It is because
> it is the natural Combination of type inference with type patterns.  And, given
> that combination, there is no need to go further in the concision department,
> and lots of reasons not to.
> Sent from my iPad
>> On Mar 4, 2020, at 5:24 AM, Tagir Valeev <amaembo at> wrote:
>> Hello!
>>> This has come up a few times.  There are several reasons to prefer the current
>>> approach, most of which stem from the prime directive, “reading code is more
>>> important than writing code.”  The argument for the compact version is really
>>> “I can do less typing”, which is a relatively weak motivation when the typing
>>> we are saving is the three characters v-a-r.
>> For me, this argument doesn't sound convincing. The problem is exactly
>> with reading: you have to read all these noise var's, this makes lines
>> longer for no big reason, your eyes need to make more horizontal
>> movements. The deconstruction (especially the nested one) might
>> include many fields, so it's not just four characters (var + space),
>> but four times the number of pattern variables (16 in the example
>> supplied by Matthias). Also, don't forget about visually impaired (not
>> totally blind) people who set very big editor font having much fewer
>> symbols fitting the screen horizontally.
>> I see the arguments below, and they look more reasonable, but probably
>> it's better to come with design decisions how all possible patterns
>> will look like before releasing the partial feature. Probably there
>> are ways to keep more common patterns shorter while allowing to write
>> more complex patterns. I don't think that we should accept the var
>> syntax solely because otherwise it might collide with the syntax of a
>> future feature, and at the same time ask "no syntax bike shedding" for
>> that future feature. What if the future feature syntax could be
>> adjusted to make the clash impossible?
>> With best regards,
>> Tagir Valeev.
>>> These are variable _declarations_, and variable declarations should look like
>>> declarations.  `int x` and `var x` look like declarations; `x` looks like a use
>>> of an existing variable.  (You might point out that we do a similar thing in
>>> lambdas, where we use an unadorned name, but the -> token is is a very, very
>>> strong indication that these are formals.  I don’t think that justification is
>>> in play here.  Note too that in lambdas you can say `(var x) -> …` now, and if
>>> we had `var` in the language when we did lambdas, we might well have not even
>>> supported the more compact `(x,y) -> …` form at the time.  So rather than this
>>> being a precedent to emulate, we might choose to view it as a historical
>>> inconvenience.)
>>> Further, down the road, we intend to have patterns that can actually take input
>>> arguments, such as `regex(“a*b*” …)`.  (Please, no syntax bike shedding on this
>>> now.)  This creates the possibility where the `x` in `` could either
>>> be an input parameter, or a constant pattern, or a fresh binding variable —
>>> this is asking a lot of readers.
>>> In the end, it comes down to: there is a benefit to being explicit (easier to
>>> spot declarations), and an additional cost to being implicit (potential for
>>> ambiguities down the road.)  The benefit for being implicit is saving the
>>> typing of three characters.  This seems a pretty easy decision.
>>>>> On Mar 3, 2020, at 9:00 AM, Matthias Perktold <tias251 at> wrote:
>>>> According to
>>>>, the
>>>> current proposal is to allow to ways of using records as deconstruction
>>>> patterns:
>>>> 1) With nested type patterns: case AddNode(Node left, Node right)) -> ...
>>>> 2) With nested var patterns: case AddNode(var left, var right)) -> ...
>>>> I was wondering whether it could make sense to allow to leave out var:
>>>> case AddNode(left, right)) -> ...
>>>> This would be especially convenient for nested record patterns.
>>>> Compare
>>>> case Line(Point(var x0, var y0), Point(var x1, var y1)) -> ...
>>>> with
>>>> case Line(Point(x0, y0), Point(x1, y1)) -> ...
>>>> The consequence would be that the syntax rules for the innermost patterns
>>>> would more closely resemble the ones for lambda parameters rather than local
>>>> variables.
>>>> Note that, there is no risk of ambiguity.
>>>> Since it appears right after case, it's clear from the context that the
>>>> whole expression is used as a pattern.
>>>> The same holds for instanceof patterns.
>>>> Now I'm sure this idea has already crossed your mind.
>>>> Did you reject it for any particular reason?
>>>> Or do you simply want to wait until you are really sure this is something
>>>> you actually want?
>>>> I realize this can be added any time in a future release.
>>>> Thanks,
>>>> Matthias

More information about the amber-dev mailing list