18477, "mppf", "What is the value of a sync variable after readFE?", "2021-09-28T20:04:41Z"
Consider the following program.
var x: sync int;
x.writeEF(1);
var y = x.readFE();
assert(y == 1); // OK this makes sense
var z = x.readXX();
writeln(z); // What value should z have? 0? 1?
My draft PR #18379 changes the behavior of this program. Before that PR, z
has the value 1
, because, readFE()
sets the sync to "empty" but doesn't change its value. Currently, with the PR, z
has the value 0
, because readFE()
"moves" out from the sync value (rather than copy-initializing) and then default-initializes the value. Intuitively, it makes sense to me that "setting the sync variable to empty will clear its value" since "empty" means the lack of a value. Additionally, I think that patterns of writeEF
and readFE
are the normal use of sync
variables that we should optimize for.
For sync owned C?
, the value type can't be copied (without modifying the RHS). So, for such types, I think we need the "move"+"default init" behavior rather than the "copy" behavior.
For what it's worth, the spec seems to be written to define the behavior in terms of separate operations on full/empty and the value, and it does not say that readFE
changes the value. (It doesn't say explicitly it preserves the value, either; but it is arguably implied).
It would be fairly easy to make the PR preserve the old behavior for numeric types. However I think that the new behavior makes more sense for records/strings/etc, because it avoids copy-initializing the record in most cases. If we changed the behavior for numeric types only, that would make it inconsistent in a way.
So I can see 3 possibilities here:
- If the value type can be copied,
readFE()
copies the value out instead of moving it, so that the old value remains - Do the above but only for numeric types or maybe POD types
-
readFE()
always moves the value out and default-initializes the "empty" sync variable's value.
Option 3. is what I have implemented currently and what I think is the most natural. In particular, it has consistent behavior for all value types.
In testing, this difference in behavior only comes up for test/arrays/deitz/jacobi*.chpl
, and there, it would be trivial to modify the test to not assume that the empty sync variable has a meaningful value.
Thoughts?