RFR: 8294943: Implement record patterns in enhanced for

Alex Buckley alex.buckley at oracle.com
Fri Oct 21 20:00:43 UTC 2022


JLS 14.14.2 comments:

1. The verbiage around "the header of the enhanced for statement" is 
painful at times, e.g. "References to the local variable declared in a 
local variable declaration contained in the header of the enhanced for 
statement from a nested class ..."

First, observe that using the word "header" in narrative text is proper 
only when the grammar has a *Header production, see 8.4 and 8.10. (Note 
that 14.14.1 doesn't have *Header, so its narrative doesn't use 
"header"; instead, its narrative refers to productions like ForInit 
directly.) Rename EnhancedForDeclaration to EnhancedForHeader so that 
"the header of the enhanced for statement" is grounded.

Second, you can generally move faster in the narrative, e.g. "The header 
of the enhanced for statement contains either (i) the declaration of a 
local variable whose name is the identifier given by 
VariableDeclaratorId ..." and "If the header of the enhanced for 
statement is a local variable declaration, the rules for the local 
variable are specified in 14.4 ..."

2. The CSR says "The record patterns are only permitted when the pattern 
is exhaustive over the enhanced for's expression." so I went looking for 
this sensible rule in 14.14.2. What I found is this note buried deep 
inside the translation items: "If T is the type of the expression 
#i.next() this translation implies both (i) the record pattern p must be 
applicable at the type T (14.30.3), and (ii) the set containing the 
record pattern p must be exhaustive for the type T (14.11.1.1)."

This relationship between the record pattern and T is critical. Hardly 
any readers will be able to join the dots offered by the current note. 
Please turn everything around: before the translation, state the 
sensible rule as plainly as possible, appending "or a compile-time error 
occurs"; then give the relationship in more detail: "Specifically, (i) 
the record pattern must be applicable at the type ... (ii) ... must be 
exhaustive ..."; and finally give a note claiming "The translation below 
implies that these properties are true."

Alex

On 10/21/2022 5:44 AM, Aggelos Biboudis wrote:
> This PR enables the ability to use record patterns in the enhanced-for, initializing the record components accordingly:
> 
> 
> record Complex(double real, double img) {}
> 
> List<Complex> list = ...;
> 
> for (Complex(var real, var img) : list) {
>      // can use “real” and “img” directly
> }
> 
> 
> This PR proposes an implementation for the "Record Patterns in Enhanced For" subtask regarding the following [CSR](https://bugs.openjdk.org/browse/JDK-8294944) (note the different JBS entries), summarised by the following:
> 
> - It enhances the grammar for the `EnhancedForStatement` to support record patterns too, alongside `LocalVariableDeclarations`.
> - Any pattern variables introduced by the record pattern in the header of the 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 in the pattern header, 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 imaginary switch would reach the default clause and end abruptly, the enhanced for each will end abruptly for the same reason.
> 
> For more information on the changes please see:
> 
> - the JEP: [JEP 432](https://openjdk.org/jeps/432)
> - the CSR: [JEP 432 - JDK-8294944](https://bugs.openjdk.org/browse/JDK-8294944)
> - the current [specification draft](https://cr.openjdk.java.net/~gbierman/jep432%2b433/jep432+433-20221018/specs/patterns-switch-record-patterns-jls.html#jls-14.14.2)
> 
> Looking forward for your review.
> 
> -------------
> 
> Commit messages:
>   - Store element type calculation result in JCEnhancedForLoop
>   - API cleanup.
>   - Adding @since, adding PreviewFeature, restoring API method.
>   - 8294943: Implement record patterns in enhanced for
> 
> Changes: https://git.openjdk.org/jdk/pull/10798/files
>   Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=10798&range=00
>    Issue: https://bugs.openjdk.org/browse/JDK-8294943
>    Stats: 602 lines in 21 files changed: 532 ins; 7 del; 63 mod
>    Patch: https://git.openjdk.org/jdk/pull/10798.diff
>    Fetch: git fetch https://git.openjdk.org/jdk pull/10798/head:pull/10798
> 
> PR: https://git.openjdk.org/jdk/pull/10798


More information about the compiler-dev mailing list