[swift-evolution] protocol can only be used as a generic constraint because it has Self or associated type requirements
Marc Knaup
marc at knaup.koeln
Mon Dec 14 09:54:07 CST 2015
Isn't this issue related to what Kotlin tries to solve with in/out
variances (and star-projection)?
https://kotlinlang.org/docs/reference/generics.html
Btw. what was the reason again that protocols use a typealias syntax
instead of "protocol Protocol<T>"?
On Mon, Dec 14, 2015 at 4:47 PM, Paul Cantrell via swift-evolution <
swift-evolution at swift.org> wrote:
> On Dec 14, 2015, at 1:37 AM, Dave Abrahams <dabrahams at apple.com> wrote:
>
>
> func maxY(p1: P, p2: P) -> Int {
> return max(p1.y, p2.y) // No problems here!
> }
>
> …right?
>
>
> Ah, but then you have the situation that P doesn't conform to P (it
> doesn't have an x that you can access). In my opinion that is just too
> weird an idea to be usable.
> Personally, I have always thought that protocols intended to be used as
> unbound existentials (not P<A: Int>, just plain P) are different beasts
> entirely from the kind used as generic constraints and should be explicitly
> declared as such—I don't think I've ever seen a protocol that is well-used
> in both ways; if you have counterexamples I'd love to see them. In
> "existential protocols," declaring an associated type or creating a self
> requirement would be an error at the point of declaration.
>
>
> IMHO, it’s an artificial distinction that makes sense only if you’re
> acclimated to Swift’s current behavior.
>
> There are plenty of situations where you really do want a generic type in
> the protocol, but you nonetheless find yourself in situations where you
> care only about the parts of the protocol that don’t depend on that generic
> type.
>
> Here’s an example, pared down a lot but taken from an actual project:
>
> protocol Request
> {
> typealias ContentType
>
>
> func onCompletion(callback: (ContentType?, ErrorType?) -> Void)
> func onSuccess(callback: ContentType -> Void)
> func onNewData(callback: ContentType -> Void)
>
> func onFailure(callback: ErrorType -> Void)
>
>
> func cancel()
> }
>
> struct RequestBatch
> {
> var requests: [Request] // Sadness. Despair. DOOOOM.
>
>
> func cancelAll()
> {
> for request in requests
> { request.cancel() }
> }
> }
>
> The current Swift solution is either to ditch the type safety of
> ContentType, or split Request into two protocols. The latter makes the API
> hard to read, and may decouple related protocol requirements that don’t
> make sense independently.
>
> On Dec 14, 2015, at 1:40 AM, ilya <ilya.nikokoshev at gmail.com> wrote:
>
> You can achieve the same result more cleanly with
>
> func maxY<T:P, U:P>(p1:T, p2: U) -> Int {
> return max(p1.y, p2.y) // No problems here!
> }
>
>
> True, but this doesn’t generalize to other contexts, e.g.
> RequestBatch.requests above.
>
> Conceptually, at least to me, a protocol describes a set of related
> capabilities that together add up to a meaningful behavior. Whether some of
> those capabilities share a generic type is incidental, and does not
> fundamentally change the nature of a protocol. Protocols should be
> protocols.
>
> Java can do this via the <?> syntax:
>
> interface Request<ContentType>
> {
> void onCompletion(CompletionCallback<ContentType> callback);
> void onSuccess(SuccessCallback<ContentType> callback);
> void onNewData(SuccessCallback<ContentType> callback);
> void onFailure(FailureCallback<ContentType> callback);
>
>
> void cancel();
> }
>
> class RequestBatch
> {
> private List<Request<?>> requests;
>
>
> public void cancelAll()
> {
> for(Request<?> request: requests)
> { request.cancel(); }
> }
> }
>
> And yes, “Java can do it” is a deliberate provocation! :P
>
> Cheers,
>
> Paul
>
> –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
> https://innig.net • @inthehands • http://siestaframework.com/
>
>
> _______________________________________________
> 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/20151214/f0788350/attachment.html>
More information about the swift-evolution
mailing list