[swift-evolution] [Proposal Draft] automatic protocol forwarding
Dave Abrahams
dabrahams at apple.com
Tue Dec 29 17:44:09 CST 2015
> On Dec 29, 2015, at 12:06 PM, Kevin Ballard via swift-evolution <swift-evolution at swift.org> wrote:
>
> I briefly skimmed your proposal, so I apologize if you already addressed this, but it occurs to me that we could support automatic protocol forwarding today on a per-protocol basis simply by declaring a separate protocol that provides default implementations doing the forwarding. Handling of Self return types can then be done by adding a required initializer (or just not implementing that method, so the concrete type is forced to deal with it even though everything else is forwarded).
>
> For example, if I want to automatically forward SequenceType to a member, I can do something like
>
> protocol SequenceTypeForwarder : SequenceType {
> typealias ForwardedSequenceType : SequenceType
>
> var forwardedSequence : ForwardedSequenceType { get }
> }
>
> extension SequenceTypeForwarder {
> func generate() -> ForwardedSequenceType.Generator {
> return forwardedSequence.generate()
> }
>
> func underestimateCount() -> Int {
> return forwardedSequence.underestimateCount()
> }
>
> func map<T>(@noescape transform: (ForwardedSequenceType.Generator.Element) throws -> T) rethrows -> [T] {
> return try forwardedSequence.map(transform)
> }
>
> func filter(@noescape includeElement: (ForwardedSequenceType.Generator.Element) throws -> Bool) rethrows -> [ForwardedSequenceType.Generator.Element] {
> return try forwardedSequence.filter(includeElement)
> }
>
> func forEach(@noescape body: (ForwardedSequenceType.Generator.Element) throws -> Void) rethrows {
> return try forwardedSequence.forEach(body)
> }
>
> func dropFirst(n: Int) -> ForwardedSequenceType.SubSequence {
> return forwardedSequence.dropFirst(n)
> }
>
> func dropLast(n: Int) -> ForwardedSequenceType.SubSequence {
> return forwardedSequence.dropLast(n)
> }
>
> func prefix(maxLength: Int) -> ForwardedSequenceType.SubSequence {
> return forwardedSequence.prefix(maxLength)
> }
>
> func suffix(maxLength: Int) -> ForwardedSequenceType.SubSequence {
> return forwardedSequence.suffix(maxLength)
> }
>
> func split(maxSplit: Int, allowEmptySlices: Bool, @noescape isSeparator: (ForwardedSequenceType.Generator.Element) throws -> Bool) rethrows -> [ForwardedSequenceType.SubSequence] {
> return try forwardedSequence.split(maxSplit, allowEmptySlices: allowEmptySlices, isSeparator: isSeparator)
> }
> }
FWIW,
https://github.com/apple/swift/blob/master/stdlib/public/core/SequenceWrapper.swift
Though I don’t know why we still have this; it’s not used anywhere and should probably be removed. I think it was supposed to be part of the new lazy sequence/collection subsystem but it was never incorporated.
> With this protocol declared, I can then say something like
>
> struct Foo {
> var ary: [Int]
> }
>
> extension Foo : SequenceTypeForwarder {
> var forwardedSequence: [Int] { return ary }
> }
>
> and my struct Foo now automatically implements SequenceType by forwarding to its variable `ary`.
>
> The downside to this is it needs to be manually declared for each protocol. But I wager that most protocols actually aren't really amenable to forwarding anyway.
>
> -Kevin Ballard
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151229/ea987285/attachment.html>
More information about the swift-evolution
mailing list