scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.81k stars 1.05k forks source link

Backward compatible serialisation for enum values #10240

Open bishabosha opened 3 years ago

bishabosha commented 3 years ago

Minimized example

As raised in the forum, perhaps sometimes you want to deprecate and remove an enum case arbitrarily, but it is still desirable to have backwards compatible serialisation.

If ordinal is canonical representation of an enum value, and frameworks use fromOrdinal for deserialisation, enum values will have to remain in code forever, to preserve the mapping between ordinals and cases.

Expectation

this user would expect a round trip solution that allows them to serialise, remove a member, and then deserialise to the same value that produced the ordinal.

Alternatives

I imagine that support for this can be provided with type class derivation

morgen-peschke commented 3 years ago

Would it be a useful capability to be able to distinguish between "this value has always been invalid", and, "this value has been deprecated," when fromOrdinal fails?

julienrf commented 3 years ago

I believe the only way to do that is to give users control on the (or on “a”) ordinal value:

sealed trait MyEnum(val ordinal: Int)
object MyEnum:
  case object Foo extends MyEnum(0)
  case object Bar extends MyEnum(1)

Then, if you remove Foo, Bar still preserves its ordinal value.

I’m not sure what enum’s ordinal is useful for, in the current state, because it could have been a useful thing for serialization but this issue shows that it shouldn’t be use like that.

I believe backward-compatible serialization is a very important topic for distributed systems. It would be nice to have better language support for designing “evolution-proof” data types, but I guess this is a bit too late for 3.0.0.

bishabosha commented 3 years ago

I believe that if the user can manually override ordinal then the Mirror framework will no longer work, due to case order not corresponding to ordinal, it also means values array will have to be deoptimised to a map for the same reason

julienrf commented 3 years ago

Yeah sure, what I meant is that users need to manage “their” ordinal, not override the enum`s ordinal.

bishabosha commented 3 years ago

Ok I see what you mean now, I didnt notice you were using case objects