This paper describes adding Rust-like ownership semantics to OCaml via the following “modes”.
- Uniqueness: an instance of a type with the
unique
mode is guaranteed to have a unique reference to its value, i.e. no instance anywhere else references the same value, so it can be mutated without unexpectedly mutating a seemingly-unrelated value. - Affinity: an instance of a type with the
affine
mode can only be used once; for example, an affine function can only be called once. In particular, a closure that in-place mutates a unique value must be affine, since in-place mutations are implemented by “consuming” the unique value and returning it mutated (see the example in section 2.2). - Locality: an instance of a type with the
local
mode can’t leave its lexical scope, i.e. is guaranteed to be allocatable on the stack. Locality allows a sort of “immutable borrow”: a unique value can be aliased as a local value, and when the local value’s scope ends, the value once again becomes unique (if it was aliased as a non-local value, the alias could’ve been stored somewhere else, so the original value is shared permanently).
Abstract:
Programmers can often improve the performance of their programs by reducing heap allocations: either by allocating on the stack or reusing existing memory in-place. However, without safety guarantees, these optimizations can easily lead to use-after-free errors and even type unsoundness. In this paper, we present a design based on modes which allows programmers to safely reduce allocations by using stack allocation and in-place updates of immutable structures. We focus on three mode axes: affinity, uniqueness and locality. Modes are fully backwards compatible with existing OCaml code and can be completely inferred. Our work makes manual memory management in OCaml safe and convenient and charts a path towards bringing the benefits of Rust to OCaml.
Another language with different modes is Granule.