I have seen users admit to choosing string literal unions as their domain representation instead of enums even when they think that enums are the more correct construct, simply because of the extra effort to write and read enum case accessing. I’ve personally been guilty of this temptation.
i.e.
type Direction = "up" | "down" | "left" | "right"
class Foo(var direction: Direction = "up")
val foo = Foo(direction = "up")
foo.direction = "left"
foo.direction match
case "up" =>
case "down" =>
case "left" =>
case "right" =>
versus
enum Direction:
case up, down, left, right
class Foo(var direction: Direction = Direction.up)
val foo = Foo(direction = Direction.up)
foo.direction = Direction.left
foo.direction match
case Direction.up =>
case Direction.down =>
case Direction.left =>
case Direction.right =>
The second is significantly more repetitive on the word Direction. While some might say they prefer the verbosity and redundancy of the second version, it is distasteful to others and does discourage them from using enums. I find it harder to read, think it wastes important horizontal space, and see no additional clarity from the explicit access in the vast majority of cases.
Swift has a language feature to make this more pleasant. When the term’s type is known to be of the enum, you can assign its value using a shorthand dot notation
enum Direction {
case up. down, left, right
}
var d: Direction = .up
d = .left
I would like to see something similar in Scala. I don’t think we would need to go the swift route of using dot notation, perhaps we could make the following work
foo.direction = up
foo.direction match
case up =>
case down =>
case left =>
case right =>
we already have something somewhat related to this idea of shorthand value creation with the new named tuples construct
type Coordinate = (x: Int, y: Int)
val a: Coordinate = (1,2)
If anyone has ideas on how this could be smoothly integrated into the language or alternate syntax, please comment.
– And yes, we could choose to import Direction.*, but this would expose the members to all files of the package and has a much higher risk of naming conflict or confusion. Also, needing to write the import does take effort, which might be enough to dissuade the programmers who don’t care too much about the readability of their code. Having it as a built-in feature as swift chose to do is the only way to make this not feel like a idiosyncratic divergence from the mainstream language.