Fw: Re: Proposal: CustomConvertible protocol


(Adrian Zubarev) #1

I know that, but I couldn’t describe it better. I mean implicit casts are already there and do look the same:

class A {}
class B: A {}

let someA: A = B() // this works fine

protocol C {}

class D: C {}

let someC: C = D() // this works fine too
Sure it depends on the context, but the implicit cast functionality could be extended on my opinion.

I build a little prototype to be able to automatically cast math expression. It looks something like this:

let someDouble = Double(UInt(0) + Int(1)) // + is overloaded

// sometimes the compiler complains so I need to write this

let someDouble = Double(UInt(0) + Int(1) as Expression)

// it would look better if we had implicit conversion enabled trough constructors
let someDouble: Double = UInt(0) + Int(1)

// or
let someDouble: Double = UInt(0) + Int(1) as Expression

···


Regards Adrian

Am 4. Dezember 2015 bei 15:15:59, Stepan Hruda (stepan.hruda@gmail.com) schrieb:

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


(Jeremy Pereira) #2

I know that, but I couldn’t describe it better. I mean implicit casts are already there and do look the same:

class A {}
class B: A {}

let someA: A = B() // this works fine

protocol C {}

class D: C {}

let someC: C = D() // this works fine too

Neither of these are casts. someA is actually a reference to the B. someC is a reference to a D (I’m not sure how the mechanism worked for structs conforming to protocols, but there’s still no instance conversion)

Sure it depends on the context, but the implicit cast functionality could be extended on my opinion.

I build a little prototype to be able to automatically cast math expression. It looks something like this:

let someDouble = Double(UInt(0) + Int(1)) // + is overloaded

// sometimes the compiler complains so I need to write this

let someDouble = Double(UInt(0) + Int(1) as Expression)

// it would look better if we had implicit conversion enabled trough constructors
let someDouble: Double = UInt(0) + Int(1)

// or
let someDouble: Double = UInt(0) + Int(1) as Expression

This used to come up on the Apple lists. A deliberate design decision was taken early on to require explicit conversion for arithmetic types on the grounds that implicit casts are a common source of error. I don’t think any proposal to add them back in is going to get very far.

···

On 4 Dec 2015, at 14:27, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:


Regards Adrian

Am 4. Dezember 2015 bei 15:15:59, Stepan Hruda (stepan.hruda@gmail.com) schrieb:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution