(The Scala Org aims to release Scala 3 by the end of fall 2020. We are about 15 employees (some of whom work part-time), spread in 4 organisations (+ active community members), focusing on finalising 52 essential projects in 6 months. As of today, project leads will publish the road-maps under the category “Scala 3 release projects” to share with you what is to be expected and hopefully get your advice & contributions as well. All the projects’ road-maps come after an extensive feedback gathering, rounds of discussion, and involvement of major stakeholders, we now need the community to help push this effort over the line. Your collaboration is highly appreciated, thank you in advance!)
The Scala Center team is working on improvements to the enumerations feature before the release of Scala 3, with these main goals in mind:
- To improve compatibility of enumerations with Java serialisation framework, and Java’s enum APIs when an enumeration extends
- To provide consistent API’s even as enum definitions grow beyond simple enumerations.
- To improve intuition behind the desugaring of enum definitions.
Milestone 1: Improve support for Java APIs
- As it stands in the
0.26.0-RC1release, if a singleton enum value does not extend
java.lang.Enumthen it will not remain singleton if it is deserialized using the Java serialization framework. This can be remedied by implementing
readResolveto replace the serialized object by one of the known constants.
java.lang.EnumAPI depends heavily on runtime checking of superclasses of enum values, so it is unsafe to extend
java.lang.Enumby more than 2 subclasses deep. When not using migration mode in the compiler, we will restrict extension of
java.lang.Enumto only from traits or the enum syntax, as it is done in Java.
- Enumerations extending
java.lang.Enumwill be restricted to only be defined in a static object, this is because the Java Language Specification forbids enums which are inner classes.
valuesarray method on the companion object of an enumeration will be sorted by ordinal.
Milestone 2: custom toString for enum
- As it stands in the
0.26.0-RC1release, a singleton enum value always overrides
toStringto be equivalent to the identifier of the enum case. This prevents customisation of
toStringby the user. We will provide a mechanism for the user to override
toStringand preserve the accuracy of APIs such as
valueOfwhich looks up values by the string of their identifier.
Milestone 3: Simplification of APIs
- We will remove
scala.runtime.EnumValuesin favour of implementing caching and lookup logic directly in the companion object of an enum.
- We will likely remove the
scala.Enumtrait while still providing dynamic lookup of the name and ordinal of each enum case. This will make it simpler to extend
java.lang.Enumwhich guarantees your enumeration has only singleton cases.
- We will standardise the representation of Java style enums in the TASTy format so that it is independent of the compiler.
Milestone 4: Improve Intuition for Enum Desugaring
- The companion of an enumeration will define public lookup methods (such as
valueOf) exactly when the enumeration only defines singleton values. It does not matter if the enumeration carries type parameters. If an enum case with a constructor is added, these lookup methods will no longer be generated.
- Enum cases that do not explicitly provide type parameters will copy the variances of type parameters of the enum that defines them. If an invariant type parameter is required by the constructor, the user will be warned to explicitly provide type parameters for the enum case
- We will experiment with improving type inference for enumerations, allowing the
applymethod of enum case companions to give the most precise type.
Thank you to Guillaume Raffin for contributing the checks that enforce enum syntax for enumerations extending
Major Changes to the Original SIP
A new change was prompted by the need for an appropriate API to retrieve the identifier of an enum value as a String, where the implementation is restricted to the compiler. In general, it is not a good choice to add a
name method, such as in
java.lang.Enum, to all enums because that is likely to collide with a
name field of a class enum case. To avoid that likely collision, the method name
enumLabel was chosen as an instance method for an enum class. As a public API,
enumLabel may be adding extra burden when we already have the similar method
enumLabel was thought to be more friendly to beginners as a teaching tool, however the need to avoid collisions generates a similarly cryptic name. An alternative is to generate a public method on the companion such as
def labelOf(value: E): String where
E is an enum type.
As with any of our announcements, we invite your feedback and discussion, as these changes will have to be reviewed by the SIP committee.