SE-0494: Add `isIdentical(to:)` Methods for Quick Comparisons to Concrete Types

I personally would choose the name isKnownIdentical or something similar because whether it returns true or false depends on implementation details of the type and it can easily provide unreliable and/or unexpected results. For instance because of the inline small string representation, this produces two identical strings:

let x = "a" + "b"
let y = "a" + "b"
x._isIdentical(to: y) // true

whereas the same operation with strings slightly longer may or may not produce identical strings:

let x = "aaaaaaaa" + "bbbbbbbb"
let y = "aaaaaaaa" + "bbbbbbbb"
x._isIdentical(to: y) // true or false, depending on optimization level

There’s no documented logic for this difference: whether the two strings are identical or not depends on internal implementation details of the type and compiler optimizations. Perhaps a future version of the standard library will produce different results, or a different version of the compiler, different constraints on the optimizer, and probably it’s already different for other architectures. If this identical check cannot have predictable semantics, this uncertainty should be reflected in the name. Using isKnown* helps portray the uncertainty, just like isKnownUniquelyReferenced which is influenced by similar factors.


Personally I’d tend to implement this with a standalone function doing a dumb bitwise comparison of the two value’s representations and tolerate the occasional false negatives when there’s a difference in padding bits. No need to add functions to every type, or for a protocol, and it works with every type out of the box. It keeps things simple… but I’ll admit I haven’t checked how often that would yield false negatives.

func isKnownIdentical<T>(_ a: T, _ b: T) -> Bool { 
   // bitwise comparison
}
7 Likes