Non-modal bounds
Externality
The externality axis records whether all a type’s values may safely be ignored
by the GC. This may be because they are OCaml “immediates” (values represented
by a tagged integer), because they are unboxed types like float# or int32#,
or because they are allocated elsewhere.
The axis has three possible values, with external_ < external64 < internal.
external_means that all values of the type are safely ignored by the GC.external64means that all values of the type are safely ignored by the GC on 64-bit systems. The only 32-bit target currently supported by the OxCaml compiler is bytecode. Note that, although JavaScript and WASM are 32-bit platforms and the compiler goes through bytecode to reach them, they still count as 64-bit systems for the purpose of this axis because of their unique data models.internalmeans values of the type may need to be scanned.
The compiler uses the externality axis for certain runtime optimizations. In
particular, updating a mutable reference to a type that is external_ can skip
the write barrier (i.e., it does not need a call to caml_modify).
In the future, we plan to make externality a mode, rather than just a property of types.
Nullability
The nullability axis records whether NULL (the machine word 0) is a possible
value of a type, and is used to support the non-allocating option 'a or_null
type. The axis has two possible values, with non_null < maybe_null. A type may
be non_null if none of its values are NULL.
The kind of values with NULL added as a possibility is written
value_or_null. The more common value kind is an abbreviation for
value_or_null mod non_null separable.
Types that don’t have NULL as a possible value are
compatible with or_null, a non-allocating option type that is built into
OxCaml. Its definition is:
type ('a : value) or_null : value_or_null =
| Null
| This of 'a
Separability
The separability axis records whether a type can have float or non-float values, where a float value is a pointer to an allocated block tagged with Double_tag (which is what float values look like).
This axis has three possible values, with non_float < separable < maybe_separable. A type is non_float if none of its elements are floats, and a type is separable if either all or none of its elements are floats. Separability is used to track types for which it is safe
to apply the float array optimization.
value_or_null is considered maybe_separable, since float or_null has both float
and non-float elements. However, all types in vanilla OCaml are separable.