Allow strengthening argument types in functions declared for protocol conformance


(Terrence Katzenbaer) #1

Because APIs are designed to be generic, protocols that must be conformed generally use types like Object or other base classes for a given framework. This introduces type casting verbosity when implementing the protocol for a specific use. I would like to see the ability to strengthen argument types in functions declared for protocol conformance.

An example:
class Foo { }

class Bar: Foo { }

protocol FooDelegate {
func didPerformSomeAction(object: Foo)
}

class FooController: FooDelegate {
func didPerformSomeAction(var object: Foo) {
// I know that object must be a Bar instance
object = object as! Bar
// do something with object
}
}

class ProposedFooController: FooDelegate { // Type 'ProposedFooController' does not conform to protocol 'FooDelegate'
func didPerformSomeAction(object: Bar) {
// do something with Bar instance
}
}

The glaring issue I see outright is how the runtime should fail when `didPerformSomeAction` in `ProposedFooController` is called with a non-Bar instance... But perhaps it /should/ fail outright because the programmer has explicitly stated that the type should be Bar.


Joining Old Orphaned Posts to the Main Threads
(Ian Ynda-Hummel) #2

-1

I think the basic problem is saying the runtime should fail. I feel like a
large part of the power of Swift is letting the compiler and the programmer
make strong assumptions about types specifically to prevent the runtime
from dealing with it.

In fact, the type system can save us here! I wrote some code you can play
with here: http://swiftstub.com/318278733

The basic idea is that if you do something like

    extension FooDelegate where Self: BarController {
        func didPerformSomeAction(object: Foo) {}
    }

calls to didPerformSomeAction with an argument of type Bar will call the
right one for the type! There might be better ways to do that, but that is
what immediately came to mind.

···

On Wed, Dec 16, 2015 at 2:43 PM Terrence Katzenbaer via swift-evolution < swift-evolution@swift.org> wrote:

Because APIs are designed to be generic, protocols that must be conformed
generally use types like Object or other base classes for a given
framework. This introduces type casting verbosity when implementing the
protocol for a specific use. I would like to see the ability to strengthen
argument types in functions declared for protocol conformance.

An example:

class Foo { }

class Bar: Foo { }

protocol FooDelegate {

    func didPerformSomeAction(object: Foo)

}

class FooController: FooDelegate {

    func didPerformSomeAction(var object: Foo) {

        // I know that object must be a Bar instance

        object = object as! Bar

        // do something with object

    }

}

class ProposedFooController: FooDelegate { // Type
'ProposedFooController' does not conform to protocol 'FooDelegate'

    func didPerformSomeAction(object: Bar) {

        // do something with Bar instance

    }

}

The glaring issue I see outright is how the runtime should fail when
`didPerformSomeAction` in `ProposedFooController` is called with a non-Bar
instance... But perhaps it /should/ fail outright because the programmer
has explicitly stated that the type should be Bar.

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


(Ian Ynda-Hummel) #3

Sorry, that should be

    extension FooDelegate where Self: BarController {
        func didPerformSomeAction(object: Bar) {}
    }

···

On Wed, Dec 16, 2015 at 3:32 PM Ian Ynda-Hummel <ianynda@gmail.com> wrote:

-1

I think the basic problem is saying the runtime should fail. I feel like a
large part of the power of Swift is letting the compiler and the programmer
make strong assumptions about types specifically to prevent the runtime
from dealing with it.

In fact, the type system can save us here! I wrote some code you can play
with here: http://swiftstub.com/318278733

The basic idea is that if you do something like

    extension FooDelegate where Self: BarController {
        func didPerformSomeAction(object: Foo) {}
    }

calls to didPerformSomeAction with an argument of type Bar will call the
right one for the type! There might be better ways to do that, but that is
what immediately came to mind.

On Wed, Dec 16, 2015 at 2:43 PM Terrence Katzenbaer via swift-evolution < > swift-evolution@swift.org> wrote:

Because APIs are designed to be generic, protocols that must be conformed
generally use types like Object or other base classes for a given
framework. This introduces type casting verbosity when implementing the
protocol for a specific use. I would like to see the ability to strengthen
argument types in functions declared for protocol conformance.

An example:

class Foo { }

class Bar: Foo { }

protocol FooDelegate {

    func didPerformSomeAction(object: Foo)

}

class FooController: FooDelegate {

    func didPerformSomeAction(var object: Foo) {

        // I know that object must be a Bar instance

        object = object as! Bar

        // do something with object

    }

}

class ProposedFooController: FooDelegate { // Type
'ProposedFooController' does not conform to protocol 'FooDelegate'

    func didPerformSomeAction(object: Bar) {

        // do something with Bar instance

    }

}

The glaring issue I see outright is how the runtime should fail when
`didPerformSomeAction` in `ProposedFooController` is called with a non-Bar
instance... But perhaps it /should/ fail outright because the programmer
has explicitly stated that the type should be Bar.

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