> From: "Brian Goetz" <[email protected]>
> To: "Remi Forax" <[email protected]>
> Cc: "Gavin Bierman" <[email protected]>, "amber-spec-experts"
> <[email protected]>
> Sent: Monday, October 24, 2022 3:17:39 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

>>> What exactly do you mean by this?
>> If i modify a record by adding a new component, i want to compiler to help 
>> me to
>> find all the switches that are using that record so i can re-evaulate if the
>> new component play a role or not for each of those codes.

> What you're asking for is cool, but enormous, because it involves introducing 
> a
> new dimension into the programming model -- time. Currently, we identify which
> modifications are binary- or source- compatible, and let people make their
> choices, but the ways in which a program has evolved over time is external to
> the programming model.
The relation to time is not something directly written in the spec but Java has 
a long tradition of offering tools to deal with the maintenance of libraries 
and applications. 

I'm not proposing to do more, but like we support the use cases related to of 
maintaining APIs through time i believe we should also support the use cases 
related to maintaining data through time. 
And obviously, because those are use cases supported by the language not more, 
people will be free to program that way or not. 

> Adding a component (and doing nothing else) is technically neither a binary- 
> nor
> source-compatible change. (Existing constructor invocations will fail to 
> link.)
> Of course, you can add a constructor overload for the old description -- and
> soon enough, you'll be able to add a deconstructor overload too.
That's why Java provides reflection or bytecode transformation or annotation 
processors, which are used to decouple de data description from the data 
implementation. 
As an example, frameworks like Spring, Quarkus, Micronaut or Helidon, all 
provide a way to map JSON objects to records in a loosely coupled way allowing 
a kind of backward compatibility. 

>> Then for each code, i can say, i do not care about that new component by 
>> adding
>> an any pattern or i care about it, add a binding and change/fix the code 
>> using
>> that binding.

> The plan for dealing with this is the same as with the constructor: write a
> deconstructor for the old description. Then all the existing match sites will
> continue to work, and you can use "find usages" to decide which ones you want
> to migrate.
In the case of APIs, we want source/binary backward compatibility, but may not 
necessarily want the same in case of data, because data may not cross 
boundaries. 
Using the same example of modern Java frameworks, all those frameworks already 
define boundaries for the user, how to define a REST API is already defined, 
how to interact with a database is already defined, etc, so as a user you are 
already inside an application with well defined boundaries. In that case, you 
do not care too much about data backward compatibility but more about having 
the data correctly describing the business and how to update those data when 
the business requirements change. 

I'm not proposing to change the language model to introduce the notion of time 
but to be able to support use cases where the data evolve through time. In my 
mind, i call that approach "data first". 
We already have features that goes in that direction, sealed types + switch 
exhaustiveness is a great way to help users to find what code should be 
upgraded when a new kind of data need to be added. 

Rémi 

Reply via email to