JDK-8294944 : Compiler implementation for Record Patterns (Second Preview)
  • Type: CSR
  • Component: tools
  • Sub-Component: javac
  • Priority: P4
  • Status: Provisional
  • Resolution: Unresolved
  • Fix Versions: 20
  • Submitted: 2022-10-07
  • Updated: 2022-11-07
Related Reports
CSR :  
Description
# Summary

Based on experiences with previous round of preview of record patterns, we propose a few improvements and simplifications of the feature.

# Problem

Three issues related to pattern matching have been identified:

 * the named record patterns (like `R(String s) r`, as opposed to the unnamed ones, like `R(String s)`) introduce an ambiguity in the grammar, and their value appears to be low,
 * another context in which specifically record patterns are useful is the enhanced for statement, where the pattern can be used to immediately split a record to components.
 * when the record type (in switch statements and expressions, or another pattern matching construct) is a generic type, the user must currently provide explicit type arguments. But, due to various constraints, the set of valid type arguments is very small, and reasonable type arguments could be inferred automatically.

# Solution

## Named Record Patterns

We propose to drop the named record patterns (i.e. record patterns, the in addition to deconstruction the record to components, also declare a new binding variable for the whole record).

## Record Patterns in Enhanced For

We propose to permit record patterns inside enhanced for:

```
record Complex(double real, double img) {}

List<Complex> list = ...;

for (Complex(var real, var img) : list) {
    //can use "real" and "img" directly
}
```

The grammar of the enhanced-for is captured by the `EnhancedForStatement` production which `LocalVariableDeclaration`s up until now. To support iteration where each element is decomposed into its components we add support for `RecordPattern`s.

Any pattern variables introduced by the record pattern are definitely matched in the statement block of the enhanced for.

The record patterns are only permitted when the pattern is exhaustive over the
enhanced for's expression. 

In the case that the element of the iteration is `null`, the switch raises a
`MatchException` wrapping the `NullPointerException`.

The enhanced for, supports record patterns for both arrays and reference types. 

Currently, the precise meaning of the enhanced for statement is given by
translation into a basic for statement. By introducing record patterns, 
the new meaning is defined by the new translation which
incorporates a switch whose selector expression is the enhanced for's
expression, and whose singleton case has the given record pattern as a sole
label would be exhaustive. Note, that in cases where the underlying switch would
reach the `default` clause and end abruptly, the enhanced for each will end
abruptly for the same reason.

## Record Pattern Type Inference

The inference update is the same as under CSR JDK-8294946. The test is copied here for completeness:

Consider code like:

```
List<String> l = ....;

switch (l) {
    case ArrayList<String> al -> {}
     ...
}
```

The current specification requires explicit type parameters for `ArrayList`,
although there are only very few possible meaningful type arguments, with
minimal differences. The proposal is to introduce type inference for type
arguments in record patterns, inferring meaningful types for the type arguments.


# Specification

The  specification draft is available for convenience here: http://cr.openjdk.java.net/~gbierman/jep432%2b433/jep432%2b433-20221028/specs/patterns-switch-record-patterns-jls.html and is attached as jls-jep432+433-20221028.zip. Please note that, for technical reasons, the specification draft also includes changes for JEP-433 (https://openjdk.org/jeps/433), which are reviewed under CSR JDK-8294946.

The specdiff for API changes is available for convenience here: http://cr.openjdk.java.net/~jlahoda/8294945/specdiff.00/overview-summary.html, and is attached as specdiff.00.zip.


Comments
Attachment <specdiff.00.zip> could not be scanned. The system has removed attachment. Please check the file before attempting to upload it again
07-11-2022

[~darcy] I have added the latest spec - which now includes type inference. However, we have decided to only support inference for record patterns, and not for type patterns. I have removed this from the description.
28-10-2022

Moving to Provisional.
20-10-2022

Attachment <specdiff.preliminary.00.zip> could not be scanned. The system has removed attachment. Please check the file before attempting to upload it again
19-10-2022