I think this problem applies to other protocols to some degree too. For example,
struct DeepThought: Codable {
let answer: 42
}
DeepThought is codable, with synthesised requirements. If a non-Codable instance property is added, it becomes un-Codable:
struct DeepThought: Codable {
let answer: 42
let question: Never
}
I guess the benefit of explicit conformance here is that the problem can be caught early, instead of waiting for type-checking or static analysis at the use site (e.g. passing an instance into an async function parameter in the case of ValueSemantic).
As discussed up-thread, ValueSemantic is more sensitive to static members and side effects, so I agree that requiring explicit conformance makes sense.
However, thinking from an API user's instead of author's perspective, explicit ValueSemantic conformance conceptually limits a lot of what a user can do without enforcing those limitations:
Borrowing @cukr's example:
struct TeamRef: CustomStringConvertible {
static let numberOfTeams = 6
// Can't allow [Int]-typed static variables here,
// because they enable reference semantics?
private static var kills: [Int] = .init(/*...*/)
private static var deaths: [Int] = .init(/*...*/)
/*...*/
var description: String {
"kd: \(kills)/\(deaths)"
}
}
I assume that all standard library types will come with ValueSemantic conformance, and some of them such as Int and String have to be explicit because they're built on reference types. Then, can users still use them to enable reference semantics for other types, as the example above? If users are discouraged from using them for anything reference-semantic, there isn't any way to actually enforce the discouragement or nudge them towards a safe default.
Also, if the user wants to extend a ValueSemantic-conforming type they don't own with something that enables reference semantics for the type, can they still do it? For example:
extension String {
static var somethingImportant: NSMutableString // could just be String, actually
}
I think the biggest problem is that we don't really have a solid definition of value semantics. When I think of value semantics, I often think in terms of if an instance and its properties (and their properties...) are passed or copied by value. Maybe I should think of this concept as a superset of value semantics.