Automatic ref/stack type selection ================================== See also: - usability_improvements.txt - automatic_deref_ux.txt Select between ref/copy automatically when it does not matter which one is used. It could also be used to shorten the syntax for var parameters (including the implicit "this" parameter). Note that copying ONLY works with: - non-private types, or - private types in private contexts in the same module (e.g. private functions) and it does NOT work with: - aliased/threaded qualifiers - if the object has some kind of "identity" which is decided by the address. And there are limitations of automatic parameters: - they cannot be assigned to a reference that has a longer lifetime than the function itself, or that require a target with "identity" based on the address. Note that small structs (that get copied) can still contain references to things with lifetime bounds. So it is in fact meaningful to have lifetime bounds on non-ref types! Overview -------- Will it work? * Function parameters/return values - Yes, it should work * Struct fields - Possibly, but it might be a bad idea. * Local variables - Yes, it should work (with reference + backing values) * Global constant data - Yes, because references aren't allowed here anyway so there is only one case to handle. So "struct fields" is the only case were it probably is tricky / a bad idea. Function parameters/return values --------------------------------- func SomeThing.work(OtherThing o) -> ReturnThing - this: can be ref or copy - o: can be ref or copy - return: copy* * it is semantically copy, but because SLUL uses the C ABI, it is probably implemented as a pointer if the value does not fit in a register. func var SomeThing.work(var OtherThing o) -> var ReturnThing - this: will be ref** - o: will be ref** - return copy* ** if the ABI has multiple return registers, and passes small results of variable parameters in output registers, it could be passed asa registers. Struct fields ------------- This could possibly work, but is it a good idea? - it requires an additional indirection - the field must be initialized: - either to a reference to a value with where the effective lifetime is "lifetime the_value >= the_struct" - or to a newly allocated item, in the same arena as the struct. - the data structure is no longer explicitly defined (it can have implicit indirection or implicit copying) So assigning to an uninitialized field could trigger arena allocation! Should it even be allowed to do it with the "=" operator, or should there be a separate operator? Or a built-in function, e.g: somestruct.field = maybe_alloc_copy(thevalue) somestruct.field = transfer(arena, thevalue) # alternative name Note that maybe_alloc_copy/transfer is a shallow copy! (It cannot be a deep copy if the struct can contain references to private types) Local variables --------------- Local variables can be turned references if: - only initialized with references to immutable data (and never from e.g. a function return value, or assinged a "ref var") Alternatively, it is possible to split local variables into two: - a reference - a backing value, that is used when a copy operation would normally have occurred. In this case, the backing value is assigned, and then the reference is set to point to the backing value. - If the reference is never used, then it can be elimitated. - If the backing value is never used, then it can be elimitated. The alternative solution is probably better. And it is fairly simple. "data" / global constant data ----------------------------- These cannot be references at all.