[swift-dev] Default implementations from protocols and ABI stability

Jordan Rose jordan_rose at apple.com
Thu Jan 11 12:46:06 CST 2018


You’re “safe" here: in a library with resilience enabled, protocol extension methods are not emitted into the client unless they’re marked @inlinable (or however that ends up being spelled when we’re done with SE-0193).

That said, you can’t be sure someone didn’t just implement their own ‘contrive()' if you put it in the protocol; if you want to defend against that you’d have to not put it in the protocol (and just provide the extension method for convenience).

Since you mentioned Collection and the standard library, I’ll also point out that the stdlib team is planning to make a lot of these methods inlinable, since they can benefit a lot from specialization (and just normal inlining, especially the ones with callbacks). That doesn’t preclude changing the implementation later, but both implementations may end up being used at run time. Still, this seems totally fine for something like ‘reduce’ that’s a pure function.

Jordan


> On Jan 11, 2018, at 10:25, Philippe Hausler via swift-dev <swift-dev at swift.org> wrote:
> 
> Given the tentative ideas already being worked on for ABI stability what would be the place that code associated with a default implementation of a method on a protocol live?
> 
> e.g.
> 
> FooKit has some code that is similar to this:
> 
> public struct SomeOptions : RawRepresentable {
>     public private(set) var rawValue: Int
>     public init(rawValue: Int) { self.rawValue = rawValue }
>     
>     public static let sensible = SomeOptions(rawValue: 1 << 0)
>     public static let maybeWillBeBetterLater = SomeOptions(rawValue: 1 << 1)
> }
> 
> public protocol Somethingable {
>     func contrive()
>     func contrive(options: SomeOptions)
> }
> 
> extension Somethingable {
>     func contrive() { contrive(options: .sensible) }
> }
> 
> Then later on in a newer version of FooKit maybeWillBeBetterLater is now MUCH better and should be the default option so the code is updated to look like this:
> 
> public struct SomeOptions : RawRepresentable {
>     public private(set) var rawValue: Int
>     public init(rawValue: Int) { self.rawValue = rawValue }
>     
>     public static let sensible = SomeOptions(rawValue: 1 << 0)
>     public static let maybeWillBeBetterLater = SomeOptions(rawValue: 1 << 1)
> }
> 
> public protocol Somethingable {
>     func contrive()
>     func contrive(options: SomeOptions)
> }
> 
> extension Somethingable {
>     func contrive() { contrive(options: .maybeWillBeBetterLater) }
> }
> 
> For apps compiled with FooKit when they are run with the new version of FooKit do they get the behavior of sensible or maybeWillBeBetterLater? 
> 
> Basically this is a question of where will the code for protocol extensions that are adopted across module boundaries live?
> 
> This interestingly applies to things like Collection and other standard library protocols and has some potential drawbacks and benefits from either way of it possibly working.
> 
> Thanks in advance for indulging my curiosity.
> Philippe
> _______________________________________________
> swift-dev mailing list
> swift-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20180111/3f9303e4/attachment.html>


More information about the swift-dev mailing list