Implementing Equatable for Protocols in Swift

Last week I attended iOSDevCampDC, where I had the pleasure of hearing @ayanonagon‘s talk on testing. You can view the code sample here.

For testing purposes and to my surprise, she implemented a default Equatable on a protocol similar to this:

I say to my surprise, because I never thought of having all objects that conform to a protocol have a default implementation like this. It definitely made me think! And of course it made sense for Ayaka’s example at the time – she added this purely for testing purposes.

But when I played around with this and thought about it some more, I started seeing future bugs. What if the value that conforms to this protocol has other properties as well. Now it has default equality that might not work as intended. For example:

Of course this would be fixed if ColorfulRectangle got it’s own custom Equatable implementation:

But the worry is that this could be easily forgotten, especially since the compiler wouldn’t complain about the equality not being implemented.

So while implementing default Equality on a Protocol level is pretty powerful, it’s also a little dangerous. Use responsibly!

Join me for a Swift Community Celebration 🎉 in New York City on September 1st and 2nd. Use code NATASHATHEROBOT to get $100 off!

Enjoy the article? Join over 17,500+ Swift developers and enthusiasts who get my weekly updates.

  • feloneouscat

    This is just as bad as how some have demonstrated Hashable (with arguments that “Oh, we don’t have to have a decent hash function, Equality will take care of that” (Eye-Roll here)

    See my article on Hashable:

    https://feloneouscat.wordpress.com/2016/03/31/stupid-hash-functions/

  • Khawer Khaliq

    Hi Natasha,

    Nice post! This is something that comes up all the time when programming to abstractions. Having faced this with projects I have been working on, I have come up with a way to deal with the issue using type erasure. This allows conforming to Equatable at the protocol level, even for protocols that don’t declare any properties, while ensuring that the actual equality comparison is made at the level of the concrete type.

    I have written a two-part post on my blog. Part one demonstrates the problems associated with trying to implement Equatable conformance or even just equality comparisons for protocols. Part two suggests a practical approach to deal with the issue using type erasure, as noted above.

    Check out the following links:

    https://khawerkhaliq.com/blog/swift-protocols-equatable-part-one/
    https://khawerkhaliq.com/blog/swift-protocols-equatable-part-two/

    Cheers, Khawer