it would be really useful to be able to declare a protocol like this:
protocol State {
associatedtype T
@enumRepresentable
static var initial: Self { get }
@enumRepresentable
static func isUpdating(_ progress: Float) -> Self
@enumRepresentable
static func didUpdate(_ value: T) -> Self
@enumRepresentable
static func didFail(_ error: Error) -> Self
}
then simply declare:
enum AsyncState: State {
typealias T = SomeType
}
and have all the cases synthesised automatically.
We could compose enums from protocols gaining flexibility and having compile time safety.
The @enumRepresentable annotation would be ignored when adopting the protocol in classes or structs.
That sounds good too, but with the annotation we'd have the flexibility of also specifying some requirements that are not enum cases in the same protocol.
Yes, I understand your reasons for the annotation – the protocol will not be constrained to enums only. The use case of having such an annotation for that reason is rather vague though.
However, this not a bad approach to the problem that was always faced with enum inheritance.
Imho that's way to much magic that isn't intuitive... inheritance for enums would be easy to understand, but using protocols for auto synthesis is a big step.
I agree that it is a big step but inheritance would prevent composition from multiple protocols and also the reason why this may be not super-intuitive is that we're not very used to think about enum cases as static vars/functions which requires a more functional mindset, but I think we Swift developers are getting there.
I would be ok with enum cases satisfying static vars from a protocol, but not sure about having this special compiler magic for automatically inferring cases when an enum conforms.
Right now, if you copy/paste the code from my pitch (without the @enumRepresentable annotations) and make the enum conform to the State protocol, you'll get an error from the compiler about duplicate symbols so I don't think it would be too "magical".