Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variants or Polymorphic variants?

I noticed that, among OCaml programmers I know, some of them always use polymorphic variants (variants that are not declared, prefixed with a backquote), while other ones never use polymorphic variants, and prefer variants declared in types.

Except for performance reasons (polymorphic variants are currently compiled less efficiently than simple variants), how do expert OCaml developers choose between them ?

like image 266
Fabrice Le Fessant Avatar asked Feb 20 '12 19:02

Fabrice Le Fessant


People also ask

What is a polymorphic variant?

Polymorphism, as related to genomics, refers to the presence of two or more variant forms of a specific DNA sequence that can occur among different individuals or populations. The most common type of polymorphism involves variation at a single nucleotide (also called a single-nucleotide polymorphism, or SNP).

What are variants in DNA?

(VAYR-ee-unt) An alteration in the most common DNA nucleotide sequence. The term variant can be used to describe an alteration that may be benign, pathogenic, or of unknown significance. The term variant is increasingly being used in place of the term mutation.

What is a variant in OCaml?

Variant types are one of the most useful features of OCaml and also one of the most unusual. They let you represent data that may take on multiple different forms, where each form is marked by an explicit tag.


2 Answers

My usage can be divided into the following 5 categories. 1. interface 2. modularity 3. legibility 4. brevity 5. tricks

  1. If the variant type is only internal to the module, I use regular variants, because as you said they are compiled more efficiently.
  2. If the variant type is exported in the interface and I feel that some cases could appear in other modules but it wouldn't necessarily make sense to make them dependend on the module, I use polymorphic variants because they are not tied to the module namespace system. Examples: the encoding type type of Xmlm. Also having the signal type as a variant type means you can develop modules using the same idea for XML processing without introducing a dependency on Xmlm.
  3. If the variant type is exported in the interface I find it sometimes too verbose to use regular variants when values of the variant type are given to functions of the module. Example: the version type of Uuidm. Instead of having to write Uuidm.create Uuidm.V4 you can simply write Uuidm.create `V4, which is as clear and less verbose.
  4. Sometimes a particular function may return different cases. If these cases are only used by this function I declare the function type in the interface without having to introduce a type definition. For example parse : string -> [`Error of string | `Ok of t]
  5. Polymorphic variants and their subtyping allow you enforce invariants statically with phantom types. Besides the possibility of defining them incrementally can be useful, both for enforcing invariants statically and for documentation purposes.

Finally I sometimes use polymorphic variants in the implementation of a module according to 4. but without them showing up in the interface. I discourage this usage unless you declare the polymorphic variants and close them because it weakens the static typing discipline.

like image 59
Daniel Bünzli Avatar answered Sep 22 '22 08:09

Daniel Bünzli


The only reason why I use polymorphic variants in most module interfaces is to work around the naming issues of classic variants.

If the following could work, polymorphic variants would no longer be useful in a majority of cases:

 type t1 = String of string | Int of int | Bool of bool | List of t1 list type t2 = String of string | Int of int | Other  let simplify x =   match (x : t1) with       String s -> String s     | Int n -> Int n     | Bool _     | List _ -> Other 

2014-02-21 Update: the code above is now valid in OCaml 4.01. Hurray!

like image 44
Martin Jambon Avatar answered Sep 23 '22 08:09

Martin Jambon