Row polymorphism

{{Short description|Kind of polymorphism}}

{{context|date=October 2018}}

In programming language type theory, row polymorphism is a kind of

polymorphism that allows one to write programs that are polymorphic on row types such as

record types and polymorphic variants.{{Cite web |title=OCaml - Polymorphic variants |url=https://v2.ocaml.org/manual/polyvariant.html |access-date=2022-12-03 |website=v2.ocaml.org}} A row-polymorphic type system and proof of type inference was introduced by Mitchell Wand.

{{cite conference

| first = Mitchell

| last = Wand

| title = Type inference for record concatenation and multiple inheritance

| book-title = Proceedings. Fourth Annual Symposium on Logic in Computer Science

| pages = 92–97

| date = June 1989

| doi = 10.1109/LICS.1989.39162

}}

{{cite journal

| first = Mitchell

| last = Wand

| title = Type inference for record concatenation and multiple inheritance

| journal = Information and Computation

| volume = 93

| issue = Selections from 1989 IEEE Symposium on Logic in Computer Science

| pages = 1–15

| date = 1991

| doi = 10.1016/0890-5401(91)90050-C

| issn = 0890-5401

| doi-access =

}}

Row-polymorphic record type definition

The row-polymorphic record type defines a list of fields with their corresponding types, a list of missing fields, and a variable indicating the absence or presence of arbitrary additional fields. Both lists are optional, and the variable may be constrained. Specifically, the variable may be "empty", indicating that no additional fields may be present for the record.

It may be written as \{\ell_1 : T_1, \dots, \ell_n : T_n, \text{absent}(f_1), \dots, \text{absent}(f_m), \rho\}. This indicates a record type that has fields \ell_i with respective types of T_i (for i = 1 \dots n), and does not have any of the fields f_j (for j = 1 \dots m), while \rho expresses the fact the record may contain other fields than \ell_i.

Row-polymorphic record types allow us to write programs that operate only on a section of a record. For example, one may define a function that performs some two-dimensional transformation that accepts a record with two or more coordinates, and returns an identical type:

\text{transform2d} : \{x : \text{Number}, y : \text{Number}, \rho\} \to \{x : \text{Number}, y : \text{Number}, \rho\}

Thanks to row polymorphism, the function may perform two-dimensional transformation on a three-dimensional (in fact, n-dimensional) point, leaving the z coordinate (or any other coordinates) intact. In a more general sense, the function can perform on any record that contains the fields x and y with type \text{Number}. There is no loss of information: the type ensures that all the fields represented by the variable \rho are present in the return type. In contrast, the type definition \{x : \text{Number}, y : \text{Number}, \mathbf{empty}\} expresses the fact that a record of that type has exactly the x and y fields and nothing else. In this case, a classic record type is obtained.

Typing operations on records

The record operations of selecting a field r.\ell, adding a field r[\ell:=e], and removing a field r \backslash \ell can be given row-polymorphic types.

\mathrm{select_\ell} = \lambda r. (r.\ell) \;:\; \{ \ell : T, \rho \} \rightarrow T

\mathrm{add_\ell} = \lambda r. \lambda e. r[\ell := e] \;:\; \{\mathrm{absent}(\ell), \rho\} \rightarrow T \rightarrow \{\ell : T, \rho\}

\mathrm{remove_\ell} = \lambda r. r \backslash \ell \;:\; \{\ell : T, \rho\} \rightarrow \{\mathrm{absent}(\ell), \rho \}

Notes