JEP 405 Record Patterns and Backwards Compatible Changes
Remi Forax
forax at univ-mlv.fr
Mon Jun 13 08:26:24 UTC 2022
----- Original Message -----
> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Nathan Walker" <nathan.h.walker at gmail.com>, "amber-dev" <amber-dev at openjdk.java.net>
> Sent: Monday, June 13, 2022 4:38:32 AM
> Subject: Re: JEP 405 Record Patterns and Backwards Compatible Changes
> First, the JLS does not commit that changing the record descriptor is a
> compatible change of any kind, binary or source. But as you say, you
> can render this "mostly compatible" by adding a constructor with the old
> record descriptor, which provides a reasonable default for the new
> components (if they are added at the end; if added in the middle, you're
> just out of luck.)
>
> Binary compatibility: given the current implementation, old match sites
> will continue to link after adding a record parameter, because both the
> instanceof test and the accessor invocations based on the old record
> descriptor still work the same way based on the new descriptor.
>
> As to source compatibility, you are correct that you are not yet able to
> declare the deconstruction pattern with the old record descriptor the
> same way you can currently with the constructor; eventually you will be
> able to do so, gaining parity with the constructor.
Brian,
I'm not convinced that source compatibility with deconstructors is a goal worth pursuing, as you say, it's only in the case where you add new components at the end, those components must have meaningful default values and the record is not serializable. So this is an awfully a very specific corner case.
For me, this is equivalent to the question: when to use a type pattern + accessors and when to use a record pattern ?
In term of backward compatibility, a type pattern + accessors enables better backward compatibility than a record pattern, because you can add new components even in the middle, it will still work. So it's not clear to me why someone will want to use a record pattern if backward compatibility is a concern.
Record patterns, by construction, matches a shape which is fixed and ordered, you only recognize those components of that length in this particular order. That adds a lot of constraints to a class/record you want to be backward compatible.
Perhaps a better road to help with backward compatibility is to have a way to specify at declaration site that using a record pattern on a record/class is disallowed, like you can have a private constructor.
And obviously, non-overloadable named pattern methods can be used in case of components that are co-dependents.
Rémi
PS: being able to juggle with several definition of a data piece with optional values, default values, etc. is a real use case, but i think it is better tackled by serializer/deserializer (in the generic sense e.g. jackson/object mapper/grpc-protobuf, etc) libraries than by the record itself.
>
> On 6/11/2022 8:39 PM, Nathan Walker wrote:
>> Currently in Java 18 we can make backwards compatible changes to the
>> contents of a record.
>>
>> Given:
>>
>> record Point(int x, int y){ }
>>
>> We can add point z with:
>>
>> record Point(int x, int y, int z) {
>>
>> @Deprecated
>> Point(int x, int y){ this(x, y, 0); }
>> }
>>
>> Or given:
>>
>> record Point(int x, int y, int z){ }
>>
>> We can remove point z with:
>>
>> record Point(int x, int y) {
>>
>> @Deprecated
>> Point(int x, int y, int z){ this(x, y); }
>>
>> @Deprecated
>> public z(){ return 0; }
>> }
>>
>> If they are marked serializable then even the serialized forms maintain
>> backwards compatibility, with the z value in the first example being
>> defaulted to 0 during deserialization, and the z in the second example
>> being ignored during deserialization.
>>
>> But if I understood JEP 405 correctly, a record pattern depends on matching
>> the exact record components. So is there a way in JEP 405 to change a
>> record's components without breaking everywhere that is using the record in
>> a pattern match statement? I would be concerned about using records in any
>> public API if every minor change to a record's structure will require a new
>> major version release under semantic versioning rules.
>>
> > Thanks for your time.
More information about the amber-dev
mailing list