[swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol<P1, P2> syntax with Any<P1, P2>

Matthew Johnson matthew at anandabits.com
Tue May 24 14:24:52 CDT 2016


> On May 24, 2016, at 2:20 PM, Austin Zheng via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I actually consider the angle brackets to be easier to read, because it's visually easy to pair the starting "<" with the ending ">" and mentally delineate the entire extent of the declaration. (I suspect I may be alone in this, though :).
> 
> If we can come up with reasonable strawman syntax for adding constraints, we should probably throw this idea into the mix. I meant to ask you earlier, but forgot. I would be happy to submit a PR to add it to the alternatives section, though, so it can be formally reviewed, discussed, and considered.

Or maybe you should put it in the future directions section?  IMO, it is pretty reasonable to consider the operator syntax to be shorthand, similar to the shorthand for Optional, Array, and Dictionary.

> 
> Austin
> 
> On Tue, May 24, 2016 at 12:07 PM, Joe Groff via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 'Any' is definitely a better name, but I think this is still syntax only a compiler can love. If we're going to repaint this bikeshed, I think we should also consider as an alternative some form of infix syntax for composing constraints. Rust uses `P1 + P2`, and various C++ proposals have suggested `P1 && P2`. Some pros(+) and cons(-) I can see with this approach:
> 
> + Infix notation works not only in type position, but constraint position as well, providing a nicer way to express multiple type variable constraints:
>         var x: P && Q
>         func foo<T: P && Q, U>(x: T)
> 
> + Infix notation feels subjectively lighter, being less nesty and angle-bracket-blinding. Compare the above with:
>         var x: Any<P, Q>
>         func foo<T: Any<P,Q>, U>(x: T)
> 
> Particularly in the second declaration, I find the nested angle brackets and comma delimiters to be hard to visually parse.
> 
> ± Like 'Any', an infix operator doesn't pass judgment on what kinds of constraint is being applied, so it naturally extends to expressing class-with-protocol constraints.
> 
> - Infix notation doesn't provide an obvious place for generalized existentials to hang secondary constraints. The angle brackets for Any provide an enclosed syntactic space we can easily stuff a 'where' clause:
> 
>         func sum(_ collection: Any<Sequence where Element == Int>) -> Int { ... }
> 
> (though this notation still feels heavy and awkward to me).
> 
> - The bracketing of `Any` might let us address the curious case of protocol vs existential metatypes in a better way. Right now, the static metatype for a protocol type (the type of `P.self`) is spelled `P.Protocol`, and the dynamic metatype for any type conforming to the protocol (the erased type of `T.self` where T: P) is spelled `P.Type`. Unintuitively, when a protocol type is substituted into `T.Type` in a generic context, you get the static type `P.Protocol` rather than `P.Type`, for soundness reasons:
> 
>         func staticType<T>(of _: T) -> T.Type { return T.self }
> 
> This substitution behavior could be made clearer if we moved a dynamic metatype's `.Type` into the Any brackets, so that `Any<P.Type>` would be the dynamic metatype of any type conforming to P, and `Any<P>.Type` would be the static metatype of the type `Any<P>`. Infix notation doesn't provide an opportunity to make this clarification.
> 
> - A few people have also noted the similarity between Any<...> and normal generic types. This is potentially confusing today, but with enough magic language features from the future, Any *could* conceivably be made a library feature in the fullness of time:
> 
>         // Let's say 'protocol' constraints indicate second-order constraint variables:
>         enum Any<Constraints: protocol> {
>                 // And we have GADTs:
>                 case value<T: Constraints>(T)
>         }
> 
>         // And we have user-defined value subtyping:
>         extension <Constraints: protocol, T: Constraints> T: Any<Constraints> { ... }
> 
> -Joe
> _______________________________________________
> 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>
> 
> _______________________________________________
> 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/20160524/0c931617/attachment.html>


More information about the swift-evolution mailing list