Proposal: CustomConvertible protocol


(Adrian Zubarev) #1

We have finally a corner where people can share their ideas on how Swift can be improved, and I’m glad my ideas might be part of this fun.

Swift introduced a few Convertible protocols, but it still needs some more If you ask me.

Something like this:

public protocol CustomConvertible {
     
    typealias CustomType
     
    public init(value: Self.CustomType) // or in a better way I can't come up with
}
But it should work in a way that we could create more different types like enums and ErrorType.

protocol AConvertible: CustomConvertible { /* some stuff here*/ }
protocol BConvertible: CustomConvertible { /* some stuff here*/ }

struct A {
    var foo: Int = 0
}

struct B {
    var boo: String = "Hello World"
}

struct C: AConvertible, BConvertible {
     
    typealias CustomAType = A
    typealias CustomBType = B
     
    var magical: SomeType
         
    init(value: CustomAType) {
        // implement it
    }
     
    init(value: CustomBType) {
        // implement it
    }
}

//===========================

let firstC: C = A() // this is what I'm missing in Swift
let secondC: C = B() // this would be a great syntax sugar
What do you think?

···


Regards Adrian


(Stepan Hruda) #2

This is not how *LiteralConvertible protocols work, though. You can only initialize variables with specific literal values recognized by the parser, it never magically casts a type to a different type for you. Similar implicit casts in my opinion confuse whoever reads the code afterwards.


class SomeConvertible: BooleanLiteralConvertible {

    typealias BooleanLiteralType = Bool

    let boolean: Bool

    internal required init(booleanLiteral value: SomeConvertible.BooleanLiteralType) {

        self.boolean = value

    }

}

func getBoolean() -> Bool {

    return false

}

let validConvertible: SomeConvertible = false

// Line below doesn’t compile

let invalidConvertible: SomeConvertible = getBoolean()

···

On Fri, Dec 4, 2015 at 8:51 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

We have finally a corner where people can share their ideas on how Swift can be improved, and I’m glad my ideas might be part of this fun.
Swift introduced a few Convertible protocols, but it still needs some more If you ask me.
Something like this:
public protocol CustomConvertible {
     
    typealias CustomType
     
    public init(value: Self.CustomType) // or in a better way I can't come up with
}
But it should work in a way that we could create more different types like enums and ErrorType.
protocol AConvertible: CustomConvertible { /* some stuff here*/ }
protocol BConvertible: CustomConvertible { /* some stuff here*/ }
struct A {
    var foo: Int = 0
}
struct B {
    var boo: String = "Hello World"
}
struct C: AConvertible, BConvertible {
     
    typealias CustomAType = A
    typealias CustomBType = B
     
    var magical: SomeType
         
    init(value: CustomAType) {
        // implement it
    }
     
    init(value: CustomBType) {
        // implement it
    }
}
//===========================
let firstC: C = A() // this is what I'm missing in Swift
let secondC: C = B() // this would be a great syntax sugar
What do you think?

Regards Adrian


(John McCall) #3

This is effectively a request for user-defined conversion operators. We actually did support those at one point in the history of Swift, but we removed them because they both introduced a lot of confusion and errors into common user idioms and were very problematic for the type-checker. It’s easy to look at obviously-contextually-typed examples like this and say that the type-checker should just make it work, but in the context of a general System F-sub type system, it is a massive source of added complexity.

In other words, at present, this is not an extension we feel we can deliver a satisfactory experience for, and to be taken seriously, any proposal is going need to demonstrate a lot of familiarity with type systems.

John.

···

On Dec 4, 2015, at 5:51 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:
We have finally a corner where people can share their ideas on how Swift can be improved, and I’m glad my ideas might be part of this fun.

Swift introduced a few Convertible protocols, but it still needs some more If you ask me.

Something like this:

public protocol CustomConvertible {
     
    typealias CustomType
     
    public init(value: Self.CustomType) // or in a better way I can't come up with
}
But it should work in a way that we could create more different types like enums and ErrorType.

protocol AConvertible: CustomConvertible { /* some stuff here*/ }
protocol BConvertible: CustomConvertible { /* some stuff here*/ }

struct A {
    var foo: Int = 0
}

struct B {
    var boo: String = "Hello World"
}

struct C: AConvertible, BConvertible {
     
    typealias CustomAType = A
    typealias CustomBType = B
     
    var magical: SomeType
         
    init(value: CustomAType) {
        // implement it
    }
     
    init(value: CustomBType) {
        // implement it
    }
}

//===========================

let firstC: C = A() // this is what I'm missing in Swift
let secondC: C = B() // this would be a great syntax sugar
What do you think?