[swift-evolution] [Pitch] Nested types in protocols (and nesting protocols in types)

Karl razielim at gmail.com
Mon Oct 17 13:29:24 CDT 2016



> On 17 Oct 2016, at 20:13, Nevin Brackett-Rozinsky <nevin.brackettrozinsky at gmail.com> wrote:
> 
> I like it!
> 
> I haven’t thought through the ramifications regarding associated types yet though.
> 

Associated types are tricky. The example I gave maybe wasn’t the most practical, as to use it you’d have to write something like:

class A<T> : MyProto where T : A.Delegate, T.ExpectedContent == String {}

which then locks you to using one static type for your delegate. Moving the associatedType up a level to MyProto means we would implement it by writing:

class A : MyProto {
    typealias ExpectedContent = String

    var delegate : A.Delegate

    func notify() {
        delegate.receive(“a string”, for: .someCase)
    }
}

class B : MyProto {
    typealias ExpectedContent = Int

    var delegate : B.Delegate

    func notify() {
        delegate.receive(42, for: .someCase)
    }
}

Still, I think the general answer to protocols with associated types for this case is: “use a concrete type in its place”.

> Is your vision that each conforming type would have to provide its own nested type as specified by the protocol?
> 
> Or could the protocol itself define a nested type and anything could use it?
> 
> protocol FloatingPoint: … {
>     enum RoundingRule {
>         // Do I put an implementation here?
>     }
> }

No, types which are defined inside the protocol are implemented there. Providing your own types to satisfy a conformance is what associated types are for.

If you wanted something like that, you could do it with a nested protocol + associated type:

protocol FloatingPoint {

    protocol _RoundingRule { func round(_ : Super) -> Super }
    associatedType RoundingRule : _RoundingRule
}

struct Float : FloatingPoint {

    enum RoundingRule : _RoundingRule {
        func round(_ val: Float) -> Float {
            /* switch self, perform rounding… */ 
        }
    }
}

That brings up an interesting point, though - we would need a way to refer to the outer protocol (I used “Super” here).

> 
> Nevin
> 
> 
> 
> On Mon, Oct 17, 2016 at 1:59 PM, Karl via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> I was just doing some googling, turns out there was a discussion about nesting protocols in other types that seemed to go positively a long time ago: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160425/016074.html <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160425/016074.html>
> 
> I would additionally like to propose that protocols be allowed to contain nested types (including other protocols). Relevant ABI issue is that the standard library contains enums for “FloatingPointRoundingRule”, “FloatingPointClassification” and “FloatingPointSign”. They would probably be better expressed as “FloatingPoint.RoundingRule”, “.Sign", etc.
> 
> so to summarise, newly legal would be:
> 
> class MyClass {
> 
>     protocol Delegate {
>     }
> }
> 
> and also:
> 
> protocol MyProto {
> 
>     enum SomeValue {
>     }
> 
>     protocol Delegate {
>         associatedType ExpectedContent
> 
> 	func receive(_: ExpectedContent, for: SomeValue)
> 
>         protocol SecondaryTarget {
>             func receive(_ : ExpectedContent)
>         }
>     }
> }
> 
> When conforming to a nested protocol, you can just use the name of the protocol:
> 
> class Host : MyProto.Delegate {
> }
> 
> Except if a protocol in the chain has associated types, then you must use a concrete, conforming type instead (as you would in the first example — MyClass.Delegate):
> 
> class SecondaryProcessor : Host.SecondaryTarget {
> }
> 
> If we’re good with this, I’ll write up a proposal.
> 
> - Karl
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 

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


More information about the swift-evolution mailing list