Compact deconstruction patterns

Brian Goetz brian.goetz at oracle.com
Tue Mar 3 11:49:08 UTC 2020


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.    

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 `Foo.bar(x)` 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 gmail.com> wrote:
> 
> According to
> https://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html, 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