Draft Spec for Fourth Preview of Pattern Matching for Switch (JEP 433) and Second Preview of Record Patterns (JEP 432) now available

Remi Forax forax at univ-mlv.fr
Fri Oct 28 07:00:33 UTC 2022


----- Original Message -----
> From: "daniel smith" <daniel.smith at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "Brian Goetz" <brian.goetz at oracle.com>, "Gavin Bierman" <gavin.bierman at oracle.com>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Sent: Friday, October 28, 2022 12:58:56 AM
> Subject: Re: Draft Spec for Fourth Preview of Pattern Matching for Switch (JEP 433) and Second Preview of Record
> Patterns (JEP 432) now available

>> On Oct 27, 2022, at 3:25 PM, forax at univ-mlv.fr wrote:
>> 
>>>> Either i can use
>>>> case Point p ->
>>>> 
>>>> or
>>>> case Point(var x, var y) ->
>>>> 
>>>> but this is not valid anymore
>>>> case Point(var x, var y) p -> ...
>>> 
>>> Can always do this, right?
>>> 
>>> case Point p where p instanceof Point(var x, var y) ->
>> 
>> Gavin already proposed that, in France, we have a sentence for that
>>  Why do it the easy way when you can do it the hard way ?  [1]
> 
> I dunno, I guess I don't really understand the motivation.
> 
> If you do 'case Point(var x, var y)', that solves your problem: won't compile if
> a new component comes along.
> 
> If you do 'case Point p', it *will* compile, of course, just like if you declare
> a field of that type. It won't check the arity, because we don't check
> properties of classes based on a random mention of them.
> 
> I guess you're really looking for something like 'case Point(#2#) p', some
> compact way to assert that the class you're talking about still has 2 record
> components.
> 
> But... this is such a niche-sounding concern to me, I don't see why *records*
> are the one kind of class in Java for which such a feature would be important.

Because one of the use case of record is to represent data and data change when requirements changed.

Here is a simple example written by one of my TA, where you want to compute something depending on some component of the record and the record as a whole

  public int maxTravelTime() {
      return passengers.stream()
          .mapToInt(p -> switch(p) {
              case Tourist(String name, boolean vip, int credits) tourist ->
                 tourist.maxHibernation() + credits / 1_000;
              case Crew(String name, int age, Rank rank) ->
                 60 - age;
          }).max().orElse(0);
  }
  
  In the case Tourist, the result depends both on some methods of the record (maxHibernation()) and the value of some component (credits).

  This code currently complies with Java 19, but it will not with Java 20.

> 
> In any case, good news—even though we don't have this dedicated feature, there
> are various ways you can mention the record class in a record pattern and get
> the compiler to make this check. Just costs a few more characters. 🤷‍♂️
> 
>> moreover this pattern+where is not exhaustive on Point.
> 
> Ah, that's interesting. I think we need to think more about what features or
> idioms we'll recommend for people to do assignment-like decomposition. I'm not
> sure that's settled yet.
> 
> If we arrive at 'RecordType instanceof RecordPattern' as a common decomposition
> idiom, then I think it would be reasonable to expect the analysis of guards
> (and probably DA/DU, etc....) to special-case this and realize it will always
> be true.

I would prefer to keep the story about where the analysis is done or not as simple as possible,
currently it's fairly simple, you have analysis inside the pattern part but not inside the where part.

That's why constant pattern is one of the next items on the roadmap BTW,
because
  case Person(String name, boolean vip) when vip ->

is not semantically equivalent to
  case Person(String name, eq true) ->  // or whatever the syntax we choose for constant patterns.

Rémi


More information about the amber-spec-observers mailing list