[swift-evolution] [Pitch] Remove type inference for associated types

Paulo Faria paulo at zewo.io
Wed Jun 29 00:17:24 CDT 2016


> On Jun 29, 2016, at 1:51 AM, Douglas Gregor <dgregor at apple.com> wrote:
> 
> which might reduce the common case for conforming to the protocol to be, e.g.,

Just discovered another horrible implication of type inference removal for the same use case. :OOO

This is the full code for the protocol

public protocol ResourceController {
    associatedtype DetailID: PathParameterInitializable = UpdateID
    associatedtype UpdateID: PathParameterInitializable
    associatedtype DestroyID: PathParameterInitializable = UpdateID

    associatedtype CreateInput: StructuredDataInitializable = UpdateInput
    associatedtype UpdateInput: StructuredDataInitializable

    associatedtype ListOutput: StructuredDataFallibleRepresentable = UpdateOutput
    associatedtype CreateOutput: StructuredDataFallibleRepresentable = UpdateOutput
    associatedtype DetailOutput: StructuredDataFallibleRepresentable = UpdateOutput
    associatedtype UpdateOutput: StructuredDataFallibleRepresentable

    func list() throws -> [ListOutput]
    func create(element: CreateInput) throws -> CreateOutput
    func detail(id: DetailID) throws -> DetailOutput
    func update(id: UpdateID, element: UpdateInput) throws -> UpdateOutput
    func destroy(id: DestroyID) throws
}

extension ResourceController {
    public func list() throws -> [ListOutput] {
        throw ClientError.notFound
    }

    public func create(element: CreateInput) throws -> CreateOutput {
        throw ClientError.notFound
    }

    public func detail(id: DetailID) throws -> DetailOutput {
        throw ClientError.notFound
    }

    public func update(id: UpdateID, element: UpdateInput) throws -> UpdateOutput {
        throw ClientError.notFound
    }

    public func destroy(id: DestroyID) throws {
        throw ClientError.notFound
    }
}

Suppose we have an implementation like this:

public struct TodoController : ResourceController {
    public typealias CreateInput = NotTodo
    public typealias UpdateInput = NotTodo

    public typealias ListOutput = NotTodo
    public typealias CreateOutput = NotTodo
    public typealias DetailOutput = NotTodo
    public typealias UpdateOutput = NotTodo

    public typealias DetailID = NotString
    public typealias UpdateID = NotString
    public typealias DestroyID = NotString

    public func list() throws -> [Todo] {
        ...
    }

    public func create(element todo: Todo) throws -> Todo {
        ...
    }

    public func detail(id: String) throws -> Todo {
        ...
    }

    public func update(id: String, element todo: Todo) throws -> Todo {
        ...
    }

    public func destroy(id: String) throws {
        ...
    }
}

Notice that the typealiases and the function declarations don’t match. But the compiler doesn’t complain because the protocol has default implementations in the protocol extension. This means that if the person implementing the protocol doesn’t make sure the types match exactly, there’s gonna be unexpected behaviour. Which I’m sure he/she will take quite some time to figure out. :(


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160629/46172673/attachment.html>


More information about the swift-evolution mailing list