Need a generic parameter to not be a class

This is starting to look like an evolution discussion. :slight_smile:

Indeed Clonable seems like a good approximation of a value-type protocol, as long as you remember to call clone() everywhere you expect a copy of the value to happen. Perhaps this could be automated in some way through a type annotation... I'm thinking of @NSCopying for @objc properties.

As others already said: A struct wrapping a class still breaks value semantic.

There are several use cases for „true structs“, but there is no mechanism to expose such traits yet, and imho protocols aren‘t the right choice here.
Maybe there are some more examples of bigger structures that "inherit" features from there components (structs or tuples that only have struct members, methods which only call nonmutating methods, functions that are build with nothing but pure functions...)?

NSDictionary's cloning behavior is a good idea for NSDictionary because of Foundation's use of mutable reference types for basic values. Swift discourages that, and that seems to have been pretty effective, so I'm not sure there's a real problem here. We can't really stop programmers from defining nonsensical conformances to Hashable, and cloning as a solution to object mutation causes its own problems.

If you're doing any work with a mutable object, you already need to have an intuition of what you're allowed to touch and what might be changing out from under you; that's just the inherent complexity of reference types. If you know that nothing's going to be modifying the object, there's no reason you shouldn't be able to put it in a Dictionary without a clone; if you don't know that, it's not clear that you can even clone it safely, because it's not like cloning is an atomic operation.

If we want to provide Midori-like language tools to help programmers manage that inherent complexity of reference types, that's great, but it's not a short-term solution, and short-term solutions like eagerly cloning aren't actually moving us incrementally towards that goal.

4 Likes

Is NSMutableString's conformance to Hashable nonsensical?

I was thinking more of a conformance that obviously doesn’t follow the rules, e.g. by returning a random number, or more plausibly just failing to be consistent with equality for innate reasons.

Arguably, it's Equatable that NSMutableString has a problem with, rather than Hashable, since that's the one that says "if these two things are ==, then you can substitute one for the other with no visible change". When working with non-immutable reference types, that grows a caveat of "as long as you don't change one of them".* Hashable just gives you a (lossy) representation of what == would check.

* This caveat actually has a lot more detail—it's closer to "as long as you don't change one of the things == checks". You could have a cache of recently-accessed offsets, say, and that would be fine because it's "just" a cache.

1 Like