and the variable r is of type t, is it guaranteed that the expression
{r with name = "Ronald"}
creates a new object i.e. is
assert (not (r == {r with name = "Ronald"}))
valid or is it possible that some optimizer in the compiler finds out that the old object is no longer used and therefore just overwrites the field name in r?
Such an optimization isnât implemented, no. But if it ever does, it wouldnât be observable with r == {r with name = "Ronald"} because then youâd be using the old value, which would disable the optimization.
As for why it isnât implemented, other than effort: Mutating pointers to the heap isnât free in GC runtimes. It involves a write barrier, which means allocating a new object can sometimes be faster than mutating an existing one, at the expense of GC pressure. Since there is a trade-off involved, such an optimization would need to make sure it only ever triggers when itâs a net benefit.
If youâve seen this optimization in other research languages, it most likely was one with reference counting instead of a tracing GC, like Koka or Lean, which also benefit from inspecting the ref-count at runtime rather than relegating this to a compile-time optimization.
In the actual default OCaml compiler, this is not possible. In the modified version of OCaml that uses the Perceus âgarbage-freeâ reference-counting algorithm, this is exactly what happens. Of course, that modified version is a proof of concept only. Itâs not a production-grade project.
There is also a similar optimisation in the compiler for the https://en.wikipedia.org/wiki/Clean\_(programming_language) programming language which uses âuniqueness typesâ, where a value can be updated in-place (and eventually deallocated at some point which is determined at compile-time), but I donât know many languages with the same feature. (I think this is actually a feature which OxCaml introduces.)
General functional programming is more ergonomic than uniqueness types, so there is a trade-off.