ValueSemantic protocol

Thanks! I've tried and known I was failing at this so many times—it's a great relief to have finally come up with something I believe in. Hopefully it stands up to poking from the likes of @Joe_Groff.

If the community adopts this definition and we move ahead with a proposal to bring support into the language what do you think we do with function types?

I don't think a useful concept of “value” exists for functions in Swift. Unlike UnsafePointer, we can't even compare two values of function type for equality. That points pretty clearly toward functions not having value semantics. Also, when there is a plausible notion of “value” that could be reflected by what happens when you call the function, e.g.

var a = 1, next = { (a, a+=1).0 }, next1 = next

next and next1 clearly don't exhibit the value-independence that would be required. You can, however, use callAsFunction to define value semantic types that are callable.

You mentioned bringing “support into the language.” The one obvious way I see to do that would be to introduce a ValueSemantic protocol whose semantic requirements match the bullet list at the top of my definition. We should definitely have that [edit: and implicit conformance of struct/enum/tuple aggregates of ValueSemantic types]. Beyond that, I'm not yet sure what kind of language features might be used to support the concept of value semantics further. I guess it would be a shame if we somehow introduced a type-system representation of purity that didn't also help us prevent errors in the definition and/or use of ValueSemantic-conforming types.

Would we do something similar to what @Chris_Lattner3 suggested here for ActorSendable ?

You mean create some refinement relationship? Yes, ValueSemantic should refine ActorSendable, as I have suggested elsewhere, because every type with value semantics has a trivial way to efficiently satisfy the ActorSendable requirements. I'd consider doing the same for Codable (the inverse of what @xwu suggested there), but:

  • The way Codable can satisfy the ActorSendable requirements ain't necessarily so efficient.
  • X: ValueSemantic, Codable would now create an ambiguous conformance.

Yeah, Never should conform to every protocol, or at least every one with no init or static requirements. If we want a less magical degenerate example, consider struct X {}. Making that conform to ValueSemantic is neither good nor bad, IMO, because while it has no useful notion of value, it also has no operations. As far as I'm concerned, go ahead if you want to :wink:

1 Like