Record pattern and enhanced for

Brian Goetz brian.goetz at
Mon Oct 24 17:06:15 UTC 2022

> Hi do not think we have yet discussed about using the record pattern in an enhanced for
> My first reaction when reading that part of the spec was, ok, cool, a bit weird to not piggyback it on pattern assignment but on the switch instead.

It's not piggybacked on either.  It's part of the Record Patterns JEP, 
which lets you put record patterns in instanceof, switch, and foreach 
contexts.  (The semantics are indeed similar to pattern assignment, so 
when that comes along, nothing new to learn.)

> But this morning in the shower, it was more, wait a minute ... it means that a record pattern and a type declaration using the same type do not work the same.
> For example, with a sealed interface I and a record Impl(int value), it's sole implementation.

Yes.  More generally, patterns are richer than assignment, and the 
semantics of foreach currently draws off of assignment semantics. We're 
currently investigating the details to broaden the interpretation of 
`for (T t : e)` to interpret `T t` as a type pattern, rather than the 
ad-hoc thing it currently is; we'll report back.

>    I hope we can keep the invariant that a record pattern and a variable declaration with the same type should both work the same way.

This is not about type patterns vs record patterns; the asymmetry you 
see here is about patterns vs non-patterns in `foreach`.  The path to 
fixing this should be to treat them all as patterns.

> There is also a minor issue that looks like an overlook but refactoring an exhanced for from using a declaration to a record pattern is a little dangerous because if the iterable is null the semantics change, with the record pattern it throws a MatchException instead of a NPE.

Yeah, it might make sense to special-case null here, though the 
MatchException has to stay in the general case of "looked exhaustive at 
compile time, but wasn't at run time."

More information about the amber-spec-experts mailing list