Swift protocols are at their most useful when they are extremely simple. Describing only one sort of requirement maximizes the number of types that can conform, and allows generic algorithms to be used more effectively.
An excellent example of this is the
Sequence protocol and its refinements: each successive protocol adds a fairly simple requirement, and enables a wealth of optimizations and generic algorithms in doing so.
But then we get to the number protocols:
AdditiveArithmetic and its refinements. And I think most agree that they are less enjoyable to work with.
AdditiveArithmetic itself is excellent, but I believe
Numeric is where it starts to go downhill. It requires
ExpressibleByIntegerLiteral for no apparent reason, and it’s horribly named: it should really be called
MultiplicativeArithmetic. Whether it should inherit
AdditiveArithmetic is a complicated question, but ultimately it’s probably fine.
SignedNumeric is immensely problematic, though: it is trivial to devise signed values that should not be multiplied (particularly when the values are meant to have associated units, like a duration), and this protocol is unusable for them.
Similar problems trickle down the entire protocol hierarchy.
ExpressibleByFloatLiteral, even though the language only has decimal and hexadecimal floating point literals. You cannot specify an unsigned number without conforming to
BinaryInteger specifically. The list goes on.
While I understand that usability is important, I feel that this could have been accomplished more easily using protocol composition and mathematical definitions. I think a lot of the protocols could also benefit from future support for “generic protocols” akin to existing generic structures, particularly when it comes to requiring a specific radix.