Have anonymous variants ever been proposed for OCaml?

Often I’ll be defining a record type like:

type adt = A of int | B of string
type t = {
  adt: adt; 
  uid: int;
} 

where I have to define some entire separate type to hold the variant. The type is never constructed by itself and it would be more convenient to just be able to write:

type t = {
  adt: A of int | B of string
  uid: int;
} 

Has this sort of anonymous variant structure ever been proposed for OCaml?

OCaml - Polymorphic variants ?

2 Likes

Since the polymorphic variants have almost all the benefits of anonymous variants without the shortcomings, I’m guessing no one seriously considered them. On the other hand, anonymous records have benefits that are missing from the pre-existing alternatives (objects).

1 Like

BTW, if the pattern above is that you specifically have the outer record to have some common fields for the variant type, then you might find it interesting to know that the OCaml native compiler has special optimizations for the opposite approach:

type t =
  | A of {uid: int; payload: int}
  | B of {uid: int; payload: string}

The above type t has a smaller representation (i.e. it takes fewer words of memory) and, more interestingly, accessing the common uid field generates very efficient code. For example, the function

let uid_of = function A {uid; _} | B {uid; _} -> uid

is compiled such that it performs no pattern matching and is essentially optimized to a single instruction. The same goes for an ad hoc match ... with like

let uid = match t with A {uid; _} | B {uid; _} -> uid in
...

See this godbolt link for the uid_of example.

I assume for the optimization to apply the common fields need to be at the same offsets in each constructor.

11 Likes