Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift comparable on a protocol

Happy new year everyone

protocol Birthday {
    var date: Date { get set }
}
    
class Person: Birthday {
    var date: Date
    var fullName: String

    // ...
}

class Car: Birthday {
    var date: Date
    var color: UIColor

    // ...
}

I want this to conform to Comparable, so I can do

Person() > Car()

Instead of

Person().date > Car().date

How can I do that? thank you so much

like image 780
אורי orihpt Avatar asked Oct 19 '25 18:10

אורי orihpt


1 Answers

You can do > trivially. Just write the following top-level function:

func > (lhs: Birthday, rhs: Birthday) -> Bool { lhs.date > rhs.date }

But you cannot conform Birthday to Comparable. Comparable requires that a type implement the following:

static func < (lhs: Self, rhs: Self) -> Bool

Self is the type that conforms to the protocol. Protocols do not conform to themselves. They are not "types." They describe types. (In some cases, an implicit existential type may be generated, but existential types cannot be manipulated in Swift.) To be comparable, a type must be able to compare itself to another thing of the same type, and you cannot get that with a protocol.

But any particular syntax you would like with your protocol you can create. You just need to write the functions.

While there is a technical limitation here (protocols don't conform to themselves), even if Swift syntax could support protocols conforming to themselves (and there are ways it could in the future), you still should never implement Comparable this way. Comparable requires Equatable. And a Person can never be Equatable to a Car. That's because Equatable requires more than a == function. It requires substitutability. If two things are "equal" in the Equatable sense, then the system can always substitute one for the other and you can never care which one it gives you. And that can't be true with with people and cars.

To avoid this kind of problem, would not recommend using < here. It implies that there is exactly one sensible ordering for these things, and "birthdate" isn't the one only order for these things. So I would definitely recommend just being explicit and comparing the dates if you want to compare dates.

like image 78
Rob Napier Avatar answered Oct 21 '25 11:10

Rob Napier