[swift-evolution] [Proposal Draft] automatic protocol forwarding
Kevin Ballard
kevin at sb.org
Tue Dec 29 14:06:48 CST 2015
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)
}
}
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151229/55040fdf/attachment.html>
More information about the swift-evolution
mailing list