ValueSemantic protocol

In a comment thread on Chris Lattner’s ActorSendable pitch, Dave Abrahams raised an interesting question: what does “value semantics” mean?

I also have to go over the argument by which Joe [Groff] has convinced me several times that value semantics is not a rigorous concept first! … It boils down mostly to the claim that the interesting property is functional purity (a version that accomodates inout) rather than anything about types, because e.g. you can always use an Int to index some global storage. The Int has value semantics, but you still produce reference semantics. There's also the fact that an UnsafePointer is totally a Value Semantic type if used only for its identity. I always leave these discussion feeling like I've just been bamboozled by his dry wit, but without a solid grasp on an answer.

I replied there that I thought I could give a rigorous enough definition, but also thought Joe would probably unravel it in two breaths. Since we’ve opened this thread…well, here’s my attempt; @Joe_Groff, do your worst!

The intuitive-but-leaky definition for Swift:

Given some variable x of type T, if T has value semantics, then it is impossible for any code to alter any visible behavior of x unless that code actually mentions x.

(Asterisk: this all goes for memory-safe code only.)

So, for example:

var x = A()
var y = x
y.mutateWildly()  // [1]
x.doStuff()       // [2]

If A is a mutable class, for example, then removing [1] could potentially alter the behavior of [2]; we’d have to understand exactly what mutateWildly and doStuff actually do.

However, if the type A has value semantics, then [1] cannot affect the results of [2] because line [1] does not mention x. I think that’s the intuition we’re trying to capture.


Joe’s as-summarized-by-Dave remarks raise several challenges to that:

  1. What if code uses an Int as a reference into some global storage?
OpenGL aside

Anybody who’s worked with OpenGL knows the…um, joys of ints that are secretly pointers to complex data structures. Ask me about the bug I once encountered where a graphics library assumed that if glRefA == glRefB then they refer to the same object, causing a bug that only happened in release builds because of ARC reordering. F U N.

  1. Doesn’t an object reference have value semantics? You just copy the reference around as a value, right?
  2. For that matter, don’t pointers have value semantics? A pointer is just a value, after all; is it the value’s fault that the memory it refers to is changing?

To answer this, I’d sharpen my definition above as follows:

  • Let x, y, z,… with types X, Y, Z,… be all the variables touched by a given Swift expression E, where “touched” means:
    • any variable that is lexically present (i.e. appears in the actual source code) for the expression,
    • plus the implicit variable memory: Memory for a dereference of any Swift *Pointer type, where Memory does not have value semantics by definition,
    • plus all the global variables touched in the transitive closure over function calls (and subscripts, getters, etc.) of E.
  • If all the types X, Y, Z,… have value semantics, then there does not exist any expression E’ that touches none of x, y, z… but whose insertion before E alters the result of E.
  • A type T has value semantics if the statement above is true for all possible E which touch a variable of T. (I have a logic mutual recursion problem here, but I think the intent is clear and it’s bedtime in Minneapolis.)

That addresses the challenges as follows:

  1. If E uses some Int as an index into global storage, then E touches that global storage — as does any E’ that alters it. Creating reference-like behavior using an Int thus does not upset the value semantics of Int itself, because the reference-like behavior also requires touching the global storage.
  2. The definition accounts for the effects of aliasing objects, making it clear that mutable class types do not have value semantics.
  3. The implicit memory variable rules out value semantics for pointer dereferences by definition.

That’s hardly a pleasant or intuitive definition of value semantics for popular consumption, and probably has a hole or two in it, but then it’s also something that this redhead just sketched out in one sitting instead of going to bed on time.

Hopefully it at least makes the case that there is some rigorous idea lurking here. Joe, pop my happy bubble!

5 Likes