[Pitch] New enum syntax.


(James Froggatt) #1

This is quite forward thinking, but since now is the time for breaking changes, I think it's an idea worth sharing.

It's recently been accepted that enum cases are values, not types, yet this is a questionable conclusion: their associated values are parameterised, unlike the main value-storage mechanisms which currently exist in the language properties and variables.
However, parameterisation has precedent in Swift, for types. I propose promoting enum cases back to types, and giving them an appropriate parameterisation syntax: Case<Type, Type>.

Suppose, in the future, we add parameters to generic types which may hold a value. By extension, it would make sense to add support for pattern matching, so the following would be possible:

struct Example<let T: Int> {} //Placeholder syntax for a value parameter.

let exampleType: Example.Type = Example<5> //No .self needed, as I believe this is soon to be removed.

switch exampleType {

case Example<0...10>: print("between 0 and 10")

case let Example<v> where v > 10: print("greater than ten")

case let Example<v> where v < 0: print("negative: \(v)")

case Example<let v>: print("other: \(v)")

}

I propose enums could be considered an extension of this idea, and each case is analogous to a nested type with generic parameters. The enum is a specialised construct for this kind of pattern matching; it resembles a metatype of its nested types, hence a variable of type Enum stores a value of Enum.Case.

The proposed syntax for enums would look like this:

enum Optional<T> {
  case Some<let T>, //Placeholder syntax for a value parameter.
  None
}

This is not a major change from the current syntax for enums, and it eliminates the currently exceptional use of round brackets for stored-value parameterisation from the language, in favour of a syntax consistent with that of type parameterisation.

This proposal has two major syntax changes:
Returning to using UpperCamelCase for enum cases, and making them analogous to nested types.
Replacement of round brackets, (), in favour of angle brackets, <>, for parameterisation of enum cases.
This could be a simple bracket replacement, which could optionally be revised in the future to match future value parameterisation of types, as shown above with the example <let T> syntax.
Alternatively, a value-parameterisation syntax could be chosen now, used for enums, and later be extended to types.

Thanks for reading. Thoughts?

PS: An alternative value parameterisation I considered when writing this proposal was Type<T = Int> and .Some<=T>, but using ‘let’ seemed more readable, and reflects pattern matching, so I used that for my examples.