In the course of exploring serialization support for records, Chris asked about the compatible evolution modes for records.  We have explored this briefly before but let's put this down in one place.

Since we are saying that records are a lot like enums, let's start with:

 A. Migrating a record-like class to a record
 B. Migrating a record to a record-like class

(which is analogous to refactoring between an enum and a class using the type-safe enum pattern.)

Migration A should be both source- and binary- compatible, provided the original class has all the members the record would have -- ctor, dtor, accessors.  Which in turn requires being able to declare the members, including dtor, but we'll come back to that.

What about serialization compatibility?  It depends on our serialization story (Chris will chime in with more here), but its fair to note that while migrating from a TSE to an enum is not serialization compatible either.

Migration B is slightly more problematic (for both records and enums), as a record will extend Record just as enums extend Enum. Which means casting to, or invoking Record methods on, a migrated record would fail.  (Same is true for enums.)  Again, I'll leave it to Chris to fill in the serialization compatibility story; we have a variety of possible approaches there.

What about changing the descriptor of a record?

 C.  Removing components
 D.  Reordering components
 E.  Adding components

Removals of all sorts are generally not source- or binary- compatible; removing components will cause public members to disappear and constructors to change their signatures.  So we should have no compatibility expectations of C.

D will cause the signature of the canonical ctor and dtor to change.  If the types of the permuted components are different, it may be possible for the author to explicitly implement the old ctor/dtor signature, so that the existing set of members is preserved.  However, I think we should describe this as not being a compatible migration, even if it is possible (in some cases) to make up the difference.

E is like D, in that it is possible to add back the old ctor/dtor implementations, and rescue existing callsites, but I think it should be put in the same category.


Reply via email to