Skip to content

Instantly share code, notes, and snippets.

@curtclifton
Created November 8, 2015 05:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save curtclifton/1923a47774a94e904bf0 to your computer and use it in GitHub Desktop.
Save curtclifton/1923a47774a94e904bf0 to your computer and use it in GitHub Desktop.
Mutually recursive protocols seem to be beyond the Swift type system currently. Or am I missing something?
//: Mutually recursive protocols?
protocol State {
typealias EventType: Event // error: type may not reference itself as a requirement
mutating func transitionWithEvent(event: EventType)
}
protocol Event {
typealias StateType: State // error: type may not reference itself as a requirement
var action: (StateMachine<StateType, Self>) -> () { get }
}
class StateMachine<S: State, E: Event> {
// …¡
}
@couchdeveloper
Copy link

It seems, it is not possible (as of today). I stumbled about the same issue, and no matter how I turned it, there's no way to realise this protocol design with structs, classes and protocol extensions. IMHO, this is a sever limitation, and together with other limitations it makes it very difficult, yet impossible, to design a "more complex" architecture. And actually, it's quite easy to get something which cannot be realised, for example any design where there is a return type, whose concrete type is not known (e.g. a protocol with type alias), or a protocol with a type alias which references back to the first protocol. You see, your design is already too complex ;)

By the way, this another example which cannot be implemented:

public protocol ClientType {
    typealias Request: RequestType
    typealias Task: TaskType
    func request() -> Request
    func task(request: Request) -> Task
    func resume(task: Task)
}

public protocol RequestType {
    typealias Client
    typealias Task
    init(client: Client)
    var client: Client { get }
    func task() -> Task
}

public protocol TaskType {
    typealias Client
    typealias Request
    init(client: Client, request: Request)
    var client: Client { get }
    func resume()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment