What bothers me quite a bit with this proposal is the conflation of two features into one construct:
- Enumerated types.
- Concise syntax for sealed types hierarchies – for instance, ADTs.
This is not the first case in the language where this happens – see implicits for example – and I believe it’s a source for confusion and an obstruction of designing syntax that is better suited / tailored to the specific needs of each feature.
Enumerated types are constant and unique values that have unique identifiers; sealed types do not exhibit any of these characteristics.
For example, what will these return?
Option.valueOf("Some")
Option.values()
They surely cannot return an instantiated object for Some
.
I suspect that the confusion between the two stems from the pattern in which enums are encoded nowadays in Scala 2 (sealed trait
+ object
s). However, it’s possible to encode them differently using opaques (which are in fact possible in Scala 2):
object Colors {
opaque type Color = Int
private[this] case class Data(name: String, rgb: Int)
private[this] val colorToData = mutable.Map.empty[Color, Data]
private[this] def apply(ordinal: Int, name: String, rgb: Int): Color = {
colorToData.put(ordinal, Data(name, rgb))
ordinal
}
object Color {
def valueOf(name: String): Color = colorToData.find(_._2.name == name).get._1
def values(): Array[Color] = colorToData.keys.toArray
val Red = Color(0, "Red", 0xFF0000)
val Green = Color(1, "Green", 0x00FF00)
val Blue = Color(2, "Blue", 0x0000FF)
}
extension ops on (color: Color) {
def ordinal: Int = color
def name: String = colorToData(color).name
def rgb: Int = colorToData(color).rgb
}
}
This is not very useful as it requires a lot of boilerplate, but this demonstrates how enums are not about sealed types, but rather about a constant set of identifiable values.