Identifiable and object identity

Opening this thread up to continue the discussion started here, about whether it's appropriate provide a default implementation relying on ObjectIdentifier.

To set expectations clearly: the proposal has been accepted and the default implementation will ship in Swift 5.1. There is no possibility of it being removed from that release, given the point we are at in the convergence of 5.1, regardless of the direction of this discussion.

That does not mean that it must remain the default implementation forever. Later releases could easily deprecate or obsolete the default implementation, especially if signal from real-world usage shows it to be problematic. My recommendation would be to wait for that signal, rather than debate hypotheticals in this thread.

Can someone "steel man" the case for ObjectIdentifier being the default?

I really can't think of a good reason for it, and I don't see why a much more unique identifier like UUID wouldn't be much better.

Where do you plan to store that UUID?

Could we? I'm not sure how this would work in practice.

1 Like

Ah I wasn't thinking about the implications of default synthesis. I see. Would still like to hear a good argument pro ObjectIdentifier though, because I don't understand it well enough

Like this:

protocol P {
  associatedtype A
  var p: A { get }
}

extension P where Self: AnyObject {
  @available(swift, obsoleted: 5.0)
  var p: ObjectIdentifier { ObjectIdentifier(self) }
}

// Error: Type 'C' does not conform to protocol 'P'
// Unavailable property 'p' was used to satisfy a requirement of protocol 'P'
class C: P { }

The error reporting could be improved, and the compiler doesn't currently warn if the default implementation of p is deprecated rather than obsoleted, but these seem like straightforward fixes.

The reason that there was so much discussion about this in the acceptance thread is that this was the main point of contention during review and it wasn't addressed by the decision notes in the acceptance thread. At first glance it might seem to be, because there's a lot of reasonable arguments there about the semantics of the protocol and the nature of default implementations, but it never makes any sort of positive case for including the conformance. So people are left with the impression that, sure, you can technically have this default implementation and document its limitations, etc, but why would you? What are the benefits? Is it expected to be correct in most cases?

4 Likes

Without commenting on the amendment, I would just like to point out the following:

If a class uses a default implementation of a protocol requirement, then its subclasses cannot override that member.

This is a known and long-standing issue, and it may be relevant here.

10 Likes