Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inline records in polymorphic variants?

The ocaml manual chapter 8 "language extensions" describes "inline records" (8.17):

The arguments of sum-type constructors can now be defined using the same syntax as records. Mutable and polymorphic fields are allowed. GADT syntax is supported. Attributes can be specified on individual fields. [...]

I am looking for that with polymorphic variants:

# type a = B of {x:int; mutable y:int} ;;
type a = B of { x : int; mutable y : int; }
# type b = `A of {u:int; mutable v:int} ;;
Line 1, characters 9-10:
Error: Syntax error

But that does not work, so right now I use an explicit auxiliary record type instead... As I understand it now, this both takes more memory and is somewhat slower.

Can I get this cool feature with polymorphic variants, too?

like image 416
repeat Avatar asked Mar 03 '23 12:03

repeat


1 Answers

In the cases of ordinary constructors, the compiler can use the type definition to distinguish between:

type t = A of int * int | B
let f = function
  | A (_,y) -> y
  | B -> 0

and

type 'a t = A of 'a | B
let f = function
  | A (_,y) -> y
  | B -> 0

Thus, it is possible to optimize the first

A (_,y) -> y

into "access the second field of the block` while still compiling the second case

A (_,y) -> y

to "access the tuple in the first field of the block, and then access the second field of the block".

For polymorphic variants, it is not possible to rely on the non-existing type definition to distinguish between those two solutions. Consequently, their memory representation must be uniform. This means that polymorphic variants always take one argument, and it is not really useful to label each argument of the constructor when there is only one argument.

This is why inline records cannot be combined with polymorphic variants.

like image 100
octachron Avatar answered Mar 06 '23 20:03

octachron