Structural Subtyping as Parametric Polymorphism

Structural subtyping and parametric polymorphism provide similar flexibility and reusability to programmers. For example, both features enable the programmer to provide a wider record as an argument to a function that expects a narrower one. However, the means by which they do so differs substantially, and the precise details of the relationship between them exists, at best, as folklore in literature. In this paper, we systematically study the relative expressive power of structural subtyping and parametric polymorphism. We focus our investigation on establishing the extent to which parametric polymorphism, in the form of row and presence polymorphism, can encode structural subtyping for variant and record types. We base our study on various Church-style λ-calculi extended with records and variants, different forms of structural subtyping, and row and presence polymorphism. We characterise expressiveness by exhibiting compositional translations between calculi. For each translation we prove a type preservation and operational correspondence result. We also prove a number of non-existence results. By imposing restrictions on both source and target types, we reveal further subtleties in the expressiveness landscape, the restrictions enabling otherwise impossible translations to be defined. More specifically, we prove that full subtyping cannot be encoded via polymorphism, but we show that several restricted forms of subtyping can be encoded via particular forms of polymorphism.


INTRODUCTION
Subtyping and parametric polymorphism offer two distinct means for writing modular and reusable code.Subtyping allows one value to be substituted for another provided that the type of the former is a subtype of that of the latter [Cardelli 1988;Reynolds 1980].Parametric polymorphism allows functions to be defined generically over arbitrary types [Girard 1972;Reynolds 1974].
There are two main approaches to syntactic subtyping: nominal subtyping [Birtwistle et al. 1979] and structural subtyping [Cardelli 1984[Cardelli , 1988;;Cardelli and Wegner 1985].The former defines a subtyping relation as a collection of explicit constraints between named types.The latter defines a subtyping relation inductively over the structure of types.This paper is concerned with the latter.For programming languages with variant types (constructor-labelled sums) and record types (fieldlabelled products) it is natural to define a notion of structural subtyping.We may always treat a variant with a collection of constructors as a variant with an extended collection of constructors (i.e., variant subtyping is covariant).Dually, we may treat a record with a collection of fields as a record with a restricted collection of those fields (i.e., record subtyping is contravariant).
We can implement similar functionality to record and variant subtyping using row polymorphism [Rémy 1994;Wand 1987].A row is a mapping from labels to types and is thus a common ingredient for defining both variants and records.Row polymorphism is a form of parametric polymorphism that allows us to abstract over the extension of a row.Intuitively, by abstracting over the possible extension of a variant or record we can simulate the act of substitution realised by structural subtyping.Such intuitions are folklore, but pinning them down turns out to be surprisingly subtle.In this paper we make them precise by way of translations between a series of different core calculi enjoying type preservation and operational correspondence results as well as non-existence results.We show that though folklore intuitions are to some extent correct, exactly how they manifest in practice is remarkably dependent on what assumptions we make, and much more nuanced than we anticipated.We believe that our results are not just of theoretical interest.It is important to carefully analyse and characterise the relative expressive power of different but related features to understand the extent to which they overlap.
To be clear, there is plenty of other work that hinges on inducing a subtyping relation based on generalisation (i.e., polymorphism) -and indeed this is the basis for principal types in Hindley-Milner type inference -but this paper is about something quite different, namely encoding prior notions of structural subtyping using polymorphism.In short, principal types concern polymorphism as subtyping, whereas this paper concerns subtyping as polymorphism.
In order to distil the features we are interested in down to their essence and eliminate the interference on the expressive power of other language features (such as higher-order store), we take plain Church-style call-by-name simply-typed -calculus ( ) as our starting point and consider the relative expressive power of minimal extensions in turn.We begin by insisting on writing explicit upcasts, type abstractions, and type applications in order to expose structural subtyping and parametric polymorphism at the term level.Later we also consider ML-style calculi, enabling new expressiveness results by exploiting the type inference for rank-1 polymorphism.For the dynamic semantics, we focus on the reduction theory generated from the -rules, adding further -rules for each term constructor and upcast rules for witnessing subtyping.
First we extend the simply-typed -calculus with variants ( [ ] ), which we then further augment with simple subtyping ( [ ] ) that only considers the subtyping relation shallowly on variant and record constructors (width subtyping), and (higher-rank) row polymorphism ( [ ] ), respectively.Dually, we extend the simply-typed -calculus with records ( ), which we then further augment with simple subtyping ( ) and (higher-rank) presence polymorphism ( ), respectively.Presence polymorphism [Rémy 1994] is a kind of dual to row polymorphism that allows us to abstract over which fields are present or absent from a record independently of their potential types, supporting a restriction of a collection of record fields, similarly to record subtyping.We then consider richer extensions with strictly covariant subtyping ( co [ ] , co ), which propagates the subtyping relation through strictly covariant positions, and full subtyping ( full [ ] , full ), which propagates the subtyping relation through any positions.We also consider target languages with both row and presence polymorphism ( [ ] , ).Our initial investigations make essential use of higher-rank polymorphism.Subsequently, we consider ML-like calculi with rank-1 row or presence polymorphism ( 1 , 1 , , which admit Hindley-Milner type inference [Damas and Milner 1982] without requirements of type annotations or explicit type abstractions and applications.The focus on rank-1 polymorphism demands a similar restriction to the calculi with subtyping ( full 1 , full 2 , full ), which constrains the positions where records and variants can appear in types.In this paper, we will consider only correspondences expressed as compositional translations inductively defined on language constructs following Felleisen [1991].In order to give a refined characterisation of expressiveness and usability of the type systems of different calculi, we make use of two orthogonal notions of local and type-only translations.
• A local translation restricts which features are translated in a non-trivial way.It provides non-trivial translations only of constructs of interest (e.g., record types, record construction and destruction, when considering record subtyping), and is homomorphic on other constructs; a global translation may allow any construct to have a non-trivial translation.• A type-only translation restricts which features a translation can use in the target language.
Every term must translate to itself modulo constructs that serve only to manipulate types (e.g., type abstraction and application); a term-involved translation has no such restriction.
Local translations capture the intuition that a feature can be expressed locally as a macro rather than having to be implemented by globally changing an entire program [Felleisen 1991].Type-only translations capture the intuition that a feature can be expressed solely by adding or removing type manipulation operations (such as upcasts, type abstraction, and type application) in terms, thereby enabling a more precise comparison between the expressiveness of different type system features.This paper gives a precise account of the relationship between subtyping and polymorphism for records and variants.We present relative expressiveness results by way of a series of translations between calculi, type preservation proofs, operational correspondence proofs, and non-existence proofs.The main contributions of the paper (summarised in Figure 1) are as follows.

EXAMPLES
To illustrate the relative expressive power of subtyping and polymorphism for variants and records with a range of extensions, we give a collection of examples.These cover the intuition behind the translations and non-existence results summarised in Figure 1 and formalised later in the paper.

Simple Variant Subtyping as Row Polymorphism
We begin with variant types.Consider the following function.In a language without subtyping ( [ ] ), we can simulate applying getAge to year by first deconstructing the variant using case and then reconstructing it at the appropriate type -a kind of generalised -expansion on variants.

This is the essence of the translation [ ]
[ ] in Section 4.1.The translation is local in the sense that it only requires us to transform the parts of the program that relate to variants (as opposed to the entire program).However, it still comes at a cost.The deconstruction and reconstruction of variants adds extra computation that was not present in the original program.
Can we achieve the same expressive power of subtyping without non-trivial term de-and reconstruction?Yes we can! Row polymorphism ( [ ] ) allows us to rewrite year with a type compatible (via row-variable substitution) with any variant type containing Year : Int and additional cases.1 year ′ = Λ .(Year 1984) [Year:Int; ]   As before, the translation to year ′ also adds new term syntax.However, the only additional syntax required by this translation involves type abstraction and type application; in other words the program is unchanged up to type erasure.Thus we categorise it as a type-only translation as opposed to the previous one which we say is term-involved.We can instantiate with (Age : Int) when applying getAge to it.The parameter type of getAge must also be translated to a row-polymorphic type, which requires higher-rank polymorphism.Moreover, we re-abstract over year ′ after instantiation to make it polymorphic again.
getAge ′ = x ∀ .[Age:Int;Year:Int; ].case (x •) {Age y ↦ → y; Year y ↦ → 2023 − y} getAge ′ (Λ .year ′ (Age : Int; )) The type application x • instantiates with the empty closed row type •.The above function application is well-typed because we ignore the order of labels when comparing rows (Age : Int; Year : Int; ≡ Year : Int; Age : Int; ) as usual.This is the essence of the local type-only translation [ ] [ ] in Section 4.2.We are relying on higher-rank polymorphism here in order to simulate upcasting on demand.For instance, an upcast on the parameter of a function of type (∀ .[Age: Int; Year : Int; ]) → B is simulated by instantiating appropriately.We will show in Section 2.4 that restricting the target language to rank-1 polymorphism requires certain constraints on the source language.

Simple Record Subtyping as Presence Polymorphism
Now, we consider record types, through the following function.In a language without subtyping ( ), we can first deconstruct the record by projection and then reconstruct it with only the required fields, similarly to the generalised -expansion of records.
getName Name = alice.NameThis is the essence of the local term-involved translation in Section 4.3.Using presence polymorphism ( ), we can simulate alice using a type-only translation.
alice ′ = Λ 1 2 .Name = "Alice"; Age = 9 Name 1 :String;Age 2 :Int The presence variables 1 and 2 can be substituted with a marker indicating that the label is either present • or absent •.We can instantiate 2 with absent • when applying getName to it, ignoring the Age label.This resolves the type mismatch as the equivalence relation on row types considers only present labels (Name : String ≡ Name : String; Age • : Int).For a general translation, we must make the parameter type of getName presence-polymorphic, and re-abstract over alice ′ .
This is the essence of the local type-only translation in Section 4.4.The duality between variants and records is reflected by the need for dual kinds of polymorphism, namely row and presence polymorphism, which can extend or shrink rows, respectively.

Exploiting Contravariance
We have now seen how to encode simple variant subtyping as row polymorphism and simple record subtyping as presence polymorphism.These encodings embody the intuition that row polymorphism supports extending rows and presence polymorphism supports shrinking rows.However, presence polymorphism is typically treated as an optional extra for row typing.For instance, Rémy [1994] uses row polymorphism for both record and variant types, and introduces presence polymorphism only to support record extension and default cases (which fall outside the scope of our current investigation).
This naturally raises the question of whether we can encode simple record subtyping using row polymorphism alone.More generally, given the duality between records and variants, can we swap the forms of polymorphism used by the above translations?
Though row polymorphism enables extending rows and what upcasting does on record types is to remove labels, we can simulate the same behaviour by extending record types that appear in contravariant positions in a type.The duality between row and presence polymorphism can be reconciled by way of the duality between covariant and contravariant positions.
Let us revisit our getName alice example, which we previously encoded using polymorphism.With row polymorphism ( ), we can give the function a row polymorphic type where the row variable appears in the record type of the function parameter.Now in order to apply getName ✗ to alice, we simply instantiate with (Age : Int).
getName ✗ (Age : Int) alice Though the above example suggests a translation which only introduces type abstractions and type applications, the idea does not extend to a general composable translation.Intuitively, the main problem is that in general we cannot know which type should be used for instantiation (Age : Int in this case) in a compositional type-only translation, which is only allowed to use the type of getName and alice ⊲ Name : String .These tell us nothing about Age : Int.
In fact, a much stronger result holds.In Section 4.5, we prove that there exists no type-only encoding of simple record subtyping into row polymorphism ( ), and dually for variant types with presence polymorphism ( [ ] [ ] ).

Full Subtyping as Rank-1 Polymorphism
The kind of translation sought in Section 2.3 cannot be type-only, as it would require us to know the type used for instantiation.A natural question is whether type inference can provide the type.
In order to support decidable, sound, and complete type inference, we consider a target calculus with rank-1 polymorphism ( 1) and Hindley-Milner type inference.Now the getName alice example type checks without an explicit upcast or type application.Type inference automatically infers a polymorphic type for getName, and instantiates the variable with Age : Int.This observation hints to us that we might encode terms with explicit record upcasts in 1 by simply erasing all upcasts (and type annotations, given that we have type inference).The global nature of erasure implies that it also works for full subtyping ( full ) which lifts the width subtyping of rows to any type by propagating the subtyping relation to the components of type constructors.For instance, the following function upcast using full subtyping is also translated into getName alice, simply by erasing the upcast.
(getName ⊲ ( Name : String; Age : Int → String)) alice Thus far, the erasure translation appears to work well even for full subtyping.Does it have any limitations?Yes, we must restrict the target language to rank-1 polymorphism, which can only generalise let-bound terms.The type check would fail if we were to bind getName viaabstraction and then use it at different record types.For instance, consider the following function which concatenates two names using the + + operator and is applied to getName.
The erasure of it is ( f .f alice ++ f bob) getName which is not well-typed as f can only have a monomorphic function type, whose parameter type cannot unify with both Name : String; Age : Int and Name : String; Year : Int .
In order to avoid such problems, we will define an erasure translation on a restricted subcalculus of full .The key idea is to give row-polymorphic types for record manipulation functions such as getName.However, the above function takes a record manipulation function of type Name : String → String as a parameter, which cannot be polymorphic as we only have rank-1 polymorphism.Inspired by the notion of rank-n polymorphism, we say that a type has rank-n records, if no path from the root of the type (seen as an abstract syntax tree) to a record type passes to the left of n or more arrows.We define the translation only on the subcalculus full 2 of full in which all types have rank-2 records.
Such an erasure translation underlies the local type-only translation full 2 1 .
We obtain a similar result for presence polymorphism.With presence polymorphism, we can make all records presence-polymorphic (similar to the translation in Section 2.2), instead of making all record manipulation functions row-polymorphic.For instance, we can infer the following types for the getName alice example.Consequently, records should appear only in positions that can be generalised with rank-1 polymorphism, which can be ensured by restricting full to the subcalculus full 1 in which all types have rank-1 records.We give a local type-only translation: full 1 1 .For variants, we can also define the notion of rank-n variants similarly.Dually to records, we can either make all variants be row-polymorphic (similar to the translation in Section 2.1) and require types to have rank-1 variants ( full [ ]1 ), or make all variant manipulation functions be presencepolymorphic and require types to have rank-2 variants ( full [ ]2 ).For instance, we can make the getAge function presence-polymorphic.We give two type-only encodings of full variant subtyping: Section 6 discusses in detail the four erasure translations from full subtyping to rank-1 polymorphism with type inference.

Strictly Covariant Record Subtyping as Presence Polymorphism
The encodings of full subtyping discussed in Section 2.4 impose restrictions on types in the source language and rely heavily on type-inference.We now consider to what extent we can support a richer form of subtyping than simple subtyping, if we turn our attention to target calculi with higher-rank polymorphism and no type inference.
One complication of extending simple subtyping to full subtyping is that if we permit propagation through contravariant positions, then the subtyping order is reversed.To avoid this scenario, we first consider strictly covariant subtyping relation derived by only propagating simple subtyping through strictly covariant positions (i.e.never to the left of any arrow).For example, the upcast getName ⊲ ( Name : String; Age : Int → String) in Section 2.4 is ruled out.We write co for our calculus with strictly covariant record subtyping.
Consider the function getChildName returning the name of the child of a person.getChildName Child = Name = carol.Child.Name In general, we can simulate the full subtyping (not only strictly covariant subtyping) of both records and variants using this technique.The nested de-and re-construction can be reformulated into coercion functions to be more compositional [Breazu-Tannen et al. 1991].In Section 5.1, we show the standard local term-involved translation formalising this idea.However, for type-only encodings, the idea of making every record presence-polymorphic in Section 2.2 does not work directly.Following that idea, we would translate carol to Now we can remove the Name of carol ′ and Age of alice ′ by instantiating 1 and 4 with •.As for simple subtyping, we make the parameter type of getChildName polymorphic, and re-abstract over carol ′ .
This is the essence of the global type-only translation co in Section 5.2.

No Type-Only Encoding of Strictly Covariant Variant Subtyping as Polymorphism
We now consider whether we could exploit hoisting of quantifiers in order to encode strictly covariant subtyping for variants ( co [ ] ) using row polymorphism.Interestingly, we will see that this cannot work, thus breaking the symmetry between the results for records and variants we have seen so far.To understand why, consider the following example involving nested variants.data = (Raw year) [Raw:[Year:Int] ]  data ⊲ [Raw : [Year : Int; Age : Int]] Following the idea of moving quantifiers, we can translate data to use a polymorphic variant, and the upcast can then be simulated by instantiation and re-abstraction.
So far, the translation appears to have worked.However, it breaks down when we consider the case split on a nested variant.For instance, consider the following function.
Using an upcast and getAge from Section 2.1 in the case clause, it accepts the nested variant data.
The difficulty with encoding parseAge with row polymorphism is that the abstraction of the row variable for the inner record of data ✗ is hoisted up to the top-level, but case split requires a monomorphic value.Thus, we must instantiate 2 with Age : Int before performing the case split.
However, this would not yield a compositional type-only translation, as the translation of the case construct only has access to the types of x and the whole case clause, which provide no information about Age : Int.Moreover, even if the translation could somehow access this type information, the translation would still fail if there were multiple incompatible upcasts of y in the case clause.
The first upcast requires 2 to be instantiated with Age : Int but the second requires it to be instantiated with the incompatible Age : String.The situation is no better if we add presence polymorphism.In Section 5.3, we prove that there exists no type-only encoding of strictly covariant variant subtyping into row and presence polymorphism ( co

No Type-Only Encoding of Full Record Subtyping as Polymorphism
For variants, we have just seen that a type-only encoding of full subtyping does not exist, even if we restrict propagation of simple subtyping to strictly covariant positions.For records, we have seen how to encode strictly covariant subtyping with presence polymorphism by hoisting quantifiers to the top-level.We now consider whether we could somehow lift the strictly covariance restriction and encode full record subtyping with polymorphism.
The idea of hoisting quantifiers does not work arbitrarily, exactly because we cannot hoist quantifiers through contravariant positions.Moreover, presence polymorphism alone cannot extend rows.Consider the full subtyping example getName ⊲ ( Name : String; Age : Int → String) from Section 2.4.The getName function is translated to the getName ′ function in Section 2.2, which provides no way to extend the parameter record type with Age : Int.
A tempting idea is to add row polymorphism: . ((x •).Name) Now we can instantiate with Age : Int to simulate the upcast.However, this still does not work.One issue is that we have no way to remove the labels introduced by the row variable in the function body, as x is only polymorphic in .For instance, consider the following upcast of the function getUnit which replaces the function body of getName with an upcast of x.
Following the above idea, getUnit is translated to getUnit ✗ = Λ .x ∀ .Name :String; .x• Then, in the translation of the upcast of getUnit, the row variable is expected to be instantiated with a row containing Age : Int.However, we cannot remove Age : Int again in the translation of the function body, meaning that the upcast inside getUnit cannot yield an empty record.
Section 5.4 expands on the discussion here and proves that there exists no type-only translation of unrestricted full record subtyping into row and presence polymorphism ( full ).

CALCULI
The foundation for our exploration of relative expressive power of subtyping and parametric polymorphism is Church's simply-typed -calculus [Church 1940].We extend it with variants and records, respectively.We further extend the variant calculus twice: first with simple structural subtyping and then with row polymorphism.Similarly, we also extend the record calculus twice: first with structural subtyping and then with presence polymorphism.In Section 5 and 6, we explore further extensions with strictly covariant subtyping, full subtyping and rank-1 polymorphism.

A Simply-Typed Base Calculus
Our base calculus is a Church-style simply typed -calculus, which we denote .Figure 2 shows the syntax, static semantics, and dynamic semantics of it.The calculus features one kind (Type) to classify well-formed types.We will enrich the structure of kinds in the subsequent sections when we add rows (e.g.Sections 3.2 and 3.5).The syntactic category of types includes abstract base types ( ) and the function types (A → B), which classify functions with domain A and codomain B. The terms consist of variables (x), -abstraction ( x A .M) binding variable x of type A in term M, and application (M N ) of M to N .We track base types in a type environment (Δ) and the type of variables in a term environment (Γ).We treat environments as unordered mappings.The static and dynamic semantics are standard.We implicitly require type annotations in terms to be well-kinded, e.g., Δ; Γ ⊢ x A .M : A → B requires Δ ⊢ A.

A Calculus with Variants [ ]
[ ] is the extension of with variants.Figure 2 incorporates the extensions to the syntax, static semantics, and dynamic semantics.Rows are the basis for variants (and later records).We assume a countably infinite set of labels L .Given a finite set of labels L, a row of kind Row L denotes a partial mapping from the cofinite set (L \ L) of all labels except those in L to types.We say that a row of kind Row ∅ is complete.A variant type ([R]) is given by a complete row R. A row is written as a sequence of pairs of labels and types.We often omit the leading •, writing e.g.ℓ 1 : A 1 , . . ., ℓ n : A n or (ℓ i : A i ) i when n is clear from context.We identify rows up to reordering of labels.Injection (ℓ M) A introduces a term of variant type by tagging the payload M with ℓ, whose resulting type is A. A case split (case M {ℓ i x i ↦ → N i } i ) eliminates an M by matching against the tags ℓ i .A successful match on ℓ i binds the payload of M to x i in N i .The kinding rules ensure that rows contain no duplicate labels.The typing rules for injections and case splits and the -rule for variants are standard.

A Calculus with Variants and Structural Subtyping [ ]
[ ] is the extension of [ ] with simple structural subtyping.Figure 3 shows the extensions to syntax, static semantics, and dynamic semantics.

Syntax. The explicit upcast operator (M
at least the same label-type pairs as row R. We write dom(R) for the domain of row R (i.e. its labels), and R| L for the restriction of R to the label set L. The T-Upcast rule enables the upcast M ⊲ B if the term M has type A and A is a subtype of B. Dynamic Semantics.The ⊲-Variant reduction rule coerces an injection (ℓ M) of type A to a larger (variant) type B. We distinguish upcast rules from rules writing instead ⊲ for the reduction relation.Correspondingly, we write ⊲ for the compatible closure of ⊲ .

Syntax
Fig. 2. Syntax, static semantics, and dynamic semantics of (unhighlighted parts), and its extensions with variants [ ] (highlighted parts with [] subscript), and records (highlighted parts with subscript).

A Calculus with Row Polymorphic Variants [ ]
[ ] is the extension of [ ] with row polymorphism.Figure 4 shows the extensions to the syntax, static semantics, and dynamic semantics.
Syntax.The syntax of types is extended with a quantified type (∀ K .A) which binds the row variable with kind K in the type A (the kinding rules restrict K to always be of kind Row L for some L).The syntax of rows is updated to allow a row to end in a row variable ( ).A row variable

Syntax
Type ∋ A :: enables the tail of a row to be extended with further labels.A row with a row variable is said to be open; a row without a row variables is said to be closed.Terms are extended with type (row) abstraction (Λ K .M) binding the row variable with kind K in M and row application (M R) of M to R. Finally, type environments are updated to track the kinds of row variables.
Static Semantics.The kinding and typing rules for row polymorphism are the standard rules for System F specialised to rows.Dynamic Semantics.The new rule -RowLam is the standard rule for System F, but specialised to rows.Though it is a rule, we use the notation to distinguish it from other rules as it only influences types.This distinction helps us to make the meta theory of translations in Section 4 clearer.We write for the compatible closure of .
3.5 A Calculus with Records is extended with records.Figure 2 incorporates the extensions to the syntax, static semantics, and dynamic semantics.As with [ ] , we use rows as the basis of record types.The extensions of kinds, rows and labels are the same as [ ] .As with variants a record type ( R ) is given by a complete row R. Records introduction ℓ i = M i i gives a record in which field i has label ℓ i and payload M i .Record projection (M.ℓ) yields the payload of the field with label ℓ from the record M. The static and dynamic semantics for records are standard.

A Calculus with Records and Structural Subtyping
is the extension of with structural subtyping.Figure 3 shows the extensions to syntax, static semantics, and dynamic semantics.The only difference from [ ] is the subtyping rule S-Record and dynamic semantics rule ⊲-Record.The subtyping relation ( ) is just like that for [ ] except R and R ′ are swapped.The S-Record rule states that a record type R is a subtype of R ′ if the row R contains at least the same label-type pairs as R ′ .The ⊲-Record rule upcasts a record ℓ i = M i i to type R by directly constructing a record with only the fields required by the supertype R .We implicitly assume that the two indexes j range over the same set of integers.

A Calculus with Presence Polymorphic Records
is the extension of with presence-polymorphic records.Figure 5 shows the extensions to the syntax, static semantics, and dynamic semantics.
Syntax.The syntax of kinds is extended with the kind of presence types (Pre).The structure of rows is updated with presence annotations on labels (ℓ P i i : A i ) i .Following Rémy [1994], a label can be marked as either absent (•), present (•), or polymorphic in its presence ( ).In each case, the label is associated with a type.Thus, it is perfectly possible to say that some label ℓ is absent with some type A. As for row variables, the syntax of types is extended with a quantified type (∀ .A), and the syntax of terms is extended with presence abstraction (Λ .M) and application (M P).To have a deterministic static semantics, we need to extend record constructions with type annotations to indicate the presence types of labels ( ℓ i = M i A ). Finally, the structure of type environments is updated to track presence variables.With presence types, we not only ignore the order of labels, but also ignore absent labels when comparing row types.Similarly when comparing two typed records in .For instance, the row  rules and write for its compatible closure.The -Project ★ rule is the same as -Project, but with a type annotation on the record.

SIMPLE SUBTYPING AS POLYMORPHISM
In this section, we consider encodings of simple subtyping.We present four encodings and two non-existence results as depicted in Figure 1.Specifically, in addition to the standard term-involved encodings of simple variant and record subtyping in Section 4.1 and Section 4.3, we give type-only encodings of simple variant subtyping as row polymorphism in Section 4.2, and simple record subtyping as presence polymorphism in Section 4.4.For each translation, we establish its correctness by demonstrating the preservation of typing derivations and the correspondence between the operational semantics.In Section 4.5, we show the non-existence of type-only encodings if we swap the row and presence polymorphism of the target languages.
Compositional Translations.We restrict our attention to compositional translations defined inductively over the structure of derivations.For convenience we will often write these as if they are defined on plain terms, but formally the domain is derivations rather than terms, whilst the codomain is terms.In this section translations on derivations will always be defined on top of corresponding compositional translations on types, kind environments, and type environments, in such a way that we obtain a type preservation property for each translation.In Sections 5 and 6 we will allow non-compositional translations on types (as they will necessarily need to be constructed in a non-compositional global fashion, e.g., by way of a type inference algorithm).

Local Term-Involved Encoding of [ ] in [ ]
We give a local term-involved compositional translation from [ ] to [ ] , formalising the idea of simulating age ⊲ [Age : Int; Year : Int] with case split and injection in Section 2.1.
The translation has a similar structure to the -expansion of variants: The following theorem states that the translation preserves typing derivations.Note that compositional translations always translate environments pointwise.For type environments, we have Γ, x : A = Γ , x : A .For kind environments, we have the identity function Δ = Δ.
In order to state an operational correspondence result, we first define ⊲ as the union of and ⊲ , and ⊲ as its compatible closure.There is a one-to-one correspondence between reduction in [ ] and reduction in [ ] .

T 4.2 (O C
).For the translation − from [ ] to [ ] , we have Intuitively, every step of -reduction in [ ] is mapped to itself in [ ] .For every step of upcast reduction of the ⊲-Variant rule guarantees that M must be a variant value.Thus, it is mapped to one step of -reduction which reduces the -expansion of M. The full proofs of type preservation and operational correspondence can be found in Appendix B.1.

Local Type-Only Encoding of [ ] in [ ]
We give a local type-only translation from [ ] to [ ] by making variants row-polymorphic, as demonstrated by year ′ and getAge ′ in Section 2.1.
The Row R is short for Row dom(R) and R\R ′ is defined as row difference: The translation preserves typing derivations.In order to state an operational correspondence result, we introduce two auxiliary reduction relations.First, we annotate the type application introduced by the translation of upcasts with the symbol @ to distinguish it from the type application introduced by the translation of case.We write for the associated reduction and for its compatible closure. -RowLam Then, we add another intuitive reduction rule for upcast in [ ] , which allows nested upcasts to reduce to a single upcast.

◮-Nested
We write ⊲◮ for the union of ⊲ and ◮ , and ⊲◮ for its compatible closure.There are one-to-one correspondences between -reductions (modulo ), and between upcast and .

T 4.4 (O C
).For the translation − from [ ] to [ ] , we have We write ? to represent zero or one step of .For the -reduction of a case-split in [ ] , in order to reduce further in [ ] , the translation of it must first reduce the empty row type application M • by .One step of upcast reduction in [ ] is simply mapped to the corresponding type application in [ ] .The other direction (reflection) is slightly more involved as one step of in [ ] may correspond to a nested upcast; hence the need for ⊲◮ instead of ⊲ .The proofs of type preservation and operational correspondence can be found in Appendix B.2.

Local Term-Involved Encoding of in
We give a local term-involved translation from to , formalising the idea of simulating alice ⊲ Name : String with projection and record construction in Section 2.1.
The translation has a similar structure to the -expanding of records, which is The translation preserves typing derivations.

R
If M N ′ , then there exists N such that N ′ * N and M ⊲ N .We write * to represent multiple (including zero) steps of .Unlike Theorem 4.2, one step of reduction in might be mapped to multiple steps of reduction in because the translation of upcast possibly introduces multiple copies of the same term.For instance, M ⊲ ℓ 1 : A; ℓ 2 : B = ℓ 1 = M .ℓ 1 ; ℓ 2 = M .ℓ 2 .One step of -reduction in M in is mapped to at least two steps of -reduction in the two copies of M in .Reflection is basically the reverse of simulation but requires at least one step of reduction in .The proofs of type preservation and operational correspondence can be found in Appendix B.3.

Local Type-Only Encoding of
in Before presenting the translation, let us focus on order of labels in types.Though generally we treat row types as unordered collections, in this section we assume, without loss of generality, that there is a canonical order on labels, and the labels of any rows (including records) conform to this order.This assumption is crucial in preserving the correspondence between labels and presence variables bound by abstraction.For example, consider the type A = ℓ 1 : A 1 ; . . .; ℓ n : A n in .Following the idea of making records presence polymorphic as exemplified by getName ′ and alice ′ in Section 2.2, this record is translated as A = ∀ 1 . . .n .ℓ 1 1 : A 1 ; . . .; ℓ n n : A n .With the canonical order, we can guarantee that ℓ i always appears at the i-th position in the record and possesses the presence variable bound at the i-th position.The full translation is as follows. where The translation preserves typing derivations.Similarly to Section 4.2, we annotate type applications introduced by the translation of upcast with @, and write for the associated reduction rule and for its compatible closure.
-PreLam (Λ .M) @ P M [P/ ] We also re-use the ◮-Nested reduction rule defined in Section 4.2.There is a one-to-one correspondence between -reductions (modulo ), and a correspondence between one upcast reduction and a sequence of reductions.

T 4.8 (O C
).The translation − from to has the following properties: , then there exists N such that N ′ * N and M ⊲◮ N .
Unlike Theorem 4.4, one step of reduction in might be mapped to multiple steps of reduction in because we might need to reduce the type application of multiple presence types in the translation results of projection and upcast.Reflection is again basically the reverse of simulation, requiring at least one step of reduction in .The proofs of type preservation and operational correspondence can be found in Appendix B.4.

Swapping Row and Presence Polymorphism
In Section 4.2 and Section 4.4, we encode simple subtyping for variants using row polymorphism, and simple subtyping for records using presence polymorphism.These encodings enjoy the property that they only introduce new type abstractions and applications.A natural question is whether we can swap the polymorphism used by the encodings meanwhile preserve the type-only property.As we have seen in Section 2. First, the type information Age : Int is not accessible to a compositional type-only translation of the function application here.Moreover, the type preservation property is also broken: alice ⊲ Name : String should have type Name : String , but here it is just translated to alice itself, which has an extra label Age in its record type.We give a general non-existence theorem.The extensions for and [ ] are straightforward and can be found in Appendix A. The proofs of this theorem can be found in Appendix E.1.We will give further non-existence results in Section 5.The core idea underlying the proofs of this kind of non-existence result is to construct counterexamples and use proof by contradiction.One important observation is that in our case a type-only translation ensures that terms are invariant under the translation modulo type abstraction and type application.As a consequence, we may characterise the general form of any such translation by accounting for the possibility of adding type abstractions and type applications in every possible position.Then we can obtain a contradiction by considering the general form of type-only translations of carefully selected terms.
The above proof relies on the assumption that translations should always satisfy the type preservation theorem.Sometimes this assumption can be too strong.In order to show the robustness of our theorem, we provide three proofs of Theorem 4.9 in Appendix E.1, where only one of them relies on type preservation.The second proof uses the compositionality and a similar argument to the getName ✗ example in Section 2.3, while the third proof does not rely on either of them.
In Section 6, we will show that it is possible to simulate record subtyping with rank-1 row polymorphism and type inference, at the cost of a weaker type preservation property and some extra conditions on the source language.
5 FULL SUBTYPING AS POLYMORPHISM So far we have only considered simple subtyping, which means the subtyping judgement applies shallowly to a single variant or record constructor (width subtyping).Any notion of simple subtyping can be mechanically lifted to full subtyping by inductively propagating the subtyping relation to the components of each type.The direction of the subtyping relation remains the same for covariant positions, and is reversed for contravariant positions.
In this section, we consider encodings of full subtyping.We first formalise the calculus full with full subtyping for records and variants, and give its standard term-involved translation to [ ] (Section 5.1).Next we give a type-only encoding of strictly covariant record subtyping (Section 5.2) .
and a non-existence result for variants (Section 5.3).Finally, we give a non-existence result for type-only encodings of full record subtyping as polymorphism (Section 5.4). .We inductively propagate the subtyping relation to sub-types, and reverse the subtyping order for function parameters because of contravariance.The reflexivity and transitivity rules are admissible.

Local Term-Involved Encoding of full
For the dynamic semantics of full , one option is to give concrete upcast rules for each value constructor, similar to [ ] and .However, as encoding full subtyping is more intricate than encoding simple subtyping (especially the encoding in Section 5.2), upcast reduction rules significantly complicate the operational correspondence theorems.To avoid such complications we adopt an erasure semantics for full [ ] which, following Pierce [2002], interprets upcasts as no-ops.The type erasure function erase(−) transforms typed terms in full [ ] to untyped terms in [ ] by erasing all upcasts and type annotations.It is given by the homomorphic extension of the following equations.

erase(M
We show a correspondence between upcasting and erasure in Appendix C.2.In the following, we always use the erasure semantics for calculi with full subtyping or strictly covariant subtyping.
The idea of the local term-involved translation from full to [ ] in Section 2.5 has been wellstudied as the coercion semantics of subtyping [Breazu-Tannen et al. 1991, 1990;Pierce 2002] We refer the reader to Pierce [2002] and Breazu-Tannen et al. [1990] for the standard type preservation and operational correspondence theorems and proofs.

Global Type-Only Encoding of co in
As a stepping stone towards exploring the possibility of type-only encodings of full subtyping, we first consider an easier problem: the encoding of co , a calculus with strictly covariant structural subtyping for records.Strictly covariant subtyping lifts simple subtyping through only the covariant positions of all type constructors.For the subtyping rule FS-Fun with the following rule which requires the parameter types to be equal: As illustrated by the examples carol ✗ and carol ′ from Section 2.5, we can extend the idea of encoding simple record subtyping as presence polymorphism described in Section 4.4 by hoisting quantifiers to the top-level, yielding a global but type-only encoding of co in .The full type and term translations are spelled out in Figure 7 together with three auxiliary functions.
where P i = i , P is a variable , ℓ i = ℓ ′ j Fig. 7.A global type-only translation from co to .
As in Section 4.4, we rely on a canonical order on labels.The auxiliary function A, P instantiates a polymorphic type A with P, simulating the type application in the term level.The auxiliary function , A takes a presence variable and a type A, and generates a sequence of presence variables based on that have the same length as the presence variables bound by A .It is used to allocate a fresh presence variable for every label in records on strictly covariant positions.We can also use it to generate a sequence of • or • for the instantiation of A by •, A and •, A .The auxiliary function , A B takes a presence variable and a subtyping relation A B, and returns a pair ( , P).The sequence of presence variables is the same as , B .The sequence of presence types are used to instantiate A to get B (as illustrated by the term translation M A ⊲ B = Λ .M P which has type B ).
The translation on types is straightforward.We not only introduce a presence variable for every element of record types, but also move the quantifiers of the types of function bodies and record elements to the top level, as they are on strictly covariant positions.While the translation on terms (derivations) may appear complicated, it mainly focuses on moving type abstractions to the top level by type application and re-abstraction using the auxiliary functions.For the projection and upcast cases, it also instantiates the sub-terms with appropriate presence types.Notice that for function application M N , we only need to move the type abstractions in M , and for projection M.ℓ j , we only need to move the type abstractions in the payload of ℓ j .
Strictly speaking, the type translation is actually not compositional because of the type application introduced by the term translation.As a consequence, in the type translation, we need to use the auxiliary function A, P which looks into the concrete structure of A instead of using it compositionally.However, we believe that it is totally fine to slightly compromise the compositionality of the type translation, which is much less interesting than the compositionality of the term translation.Moreover, we can still make the type translation compositional by extending the type syntax with type operators and type-level type application of System F .
We have the following type preservation theorem.The proof shown in Appendix C.3 follows from induction on typing derivations of co .
In order to state an operational correspondence result, we use the erasure semantics for given by the standard type erasure function defined as the homomorphic extension of the following equations.
Since the terms in co and are both erased to untyped , for the operational correspondence we need only show that any term in co is still erased to the same term after translation.

T 5.2 (O C
).The translation − from co to satisfies the equation erase(M) = erase( M ) for any well-typed term M in co .

P
. By straightforward induction on M.
By using erasure semantics, the operational correspondence becomes concise and obvious for type-only translations, as all constructs introduced by type-only translations are erased by type erasure functions.It is also possible to reformulate Theorem 4.4 and Theorem 4.8 to use erasure semantics, but the current versions are somewhat more informative and not excessively complex.

Non-Existence of Type-Only Encodings of co [ ]
in [ ] As illustrated by the example parseAge ✗ data ✗ in Section 2.6, the approach of hoisting quantifiers to the top-level does not work for variants, because of case splits.Formally, we have the following general non-existence theorem showing that no other approaches exist.

T 5.3. There exists no global type-only encoding of co
The idea of the proof is the same as that of Theorem 4.9 which we have shown in Section 4.5: construct the schemes of type-only translations for certain terms and derive a contradiction.The terms we choose here are the nested variant M = (ℓ (ℓ y) [ℓ ] ) [ℓ:[ℓ ] ] for some free term variable y in the environment together with its upcast }, similar to the counterexamples we give in Section 2.6.To obtain a contradiction, we show that we cannot give a uniform type-only translation of M such that both M 1 and M 2 can be translated compositionally.The details of the proof can be found in Appendix E.2.
As a corollary, there can be no global type-only encoding of full record extensions.In their translation, a variant is translated to a function which takes a record of functions.For instance, the translation of variant types is: In fact, there is no contradiction because a variant in a covariant position corresponds to a record in a contravariant position, which means that the encoding of co in Section 5.2 cannot be used.Moreover, the translation from variants to records is not type-only as it introduces -abstractions.

Non-Existence of Type-Only Encodings of full in As illustrated by the examples getName ′
✗ and getUnit ✗ in Section 2.7, one attempt to simulate full record subtyping by both making record types presence-polymorphic and adding row variables for records in contravariant positions fails.In fact no such encoding exists.
T 5.4.There exists no global type-only encoding of full in .
Again, the proof idea is to give general forms of type-only translations for certain terms and proof by contradiction.Our choice of terms here are different from the counterexamples in Section 2.7 this time.Instead, we first consider two functions f 1 = x .xand f 2 = x . of the same type → .Any type-only translations of these functions must yield terms of the following forms: By type preservation, they should have the same type, which means x B 1 and (Λ .) B 2 should also have the same type.As a result, the type A 1 of x cannot contain any type variables bound in 1 unless they are inside the type of some labels which are instantiated to absent by the type application x B 1 .Then, it is problematic when we want to upcast the parameter of f 1 to be a wider record, e.g., f 1 ⊲ ( ℓ : → ).Intuitively, because A 1 cannot be an open record type with the row variable bound in 1 , we actually have no way to expand A 1 , which leads to a contradiction.The full proof can be found in Appendix E.3.

FULL SUBTYPING AS RANK-1 POLYMORPHISM
In Section 4.5, we showed that no type-only encoding of record subtyping as row polymorphism exists.The main obstacle is a lack of type information for instantiation.By focusing on rank-1 polymorphism in the target language, we need no longer concern ourselves with type abstraction and application explicitly anymore.Instead we defer to Hindley-Milner type inference [Damas and Milner 1982] as demonstrated by the examples in Section 2.4.In this section, we formalise the encodings of full subtyping as rank-1 polymorphism.
Here we focus on the encoding of full in 1 , a ML-style calculus with records and rank-1 row polymorphism (the same idea applies to each combination of encoding records or variants as rank-1 row polymorphism or rank-1 presence polymorphism).The specification of 1 is given in Appendix A.3, which uses a standard declarative Hindley-Milner style type system and extends the term syntax with let-binding let x = M in N for polymorphism.We also extend full with let-binding syntax and its standard typing and operational semantics rules.As demonstrated in Section 2.4, we can use the following (local and type-only) erasure translation to encode full 2 , the fragment of full where types are restricted to have rank-2 records, in 1 .
Since the types of translated terms in 1 are given by type inference, we do not need to use a translation on types in the translation on terms.Moreover, we implicitly allow type annotations on -abstractions to be erased as they no longer exist in the target language.
To formalise the definition of rank-n records defined in Section 2.4, we introduce the predicate ℧ n (A) defined as follows for any natural number n.
We define a type A to have rank-n records, if ℧ n (A) holds.The predicate ℧ n (A) basically means no record types can appear in the left subtrees of n or more arrows.
The operational correspondence of the erasure translation comes for free.Note that both full 2 and 1 are type erased to untyped .The type erasure function of full 2 inherited from full [ ] in Section 5.1 is identical to the erasure translation.The type erasure function erase(−) of 1 is simply the identity function (as there is no type annotation at all).We have the following theorem.Proving type preservation is more challenging.To avoid the complexity of reasoning about type inference, we state the type preservation theorem using the declarative type system of 1 , which requires us to give translations on types.We define the translations on types and environments in Figure 8.As in Section 4.4 and Section 5.2, we assume a canonical order on labels and require all rows and records to conform to this order.The translation on type environments is still the identity Δ = Δ.To define the translation on term environments, we need to explicitly distinguish between variables bound by and variables bound by let.We write a, b for the former, and x, y for the latter.Because the translation on term environments may introduce fresh free type variables which are not in the original type environments, we define Δ; Γ as a shortcut for ( Δ , v( Γ )); Γ .
The type translation A returns a type scheme.It opens up row types in A that appear strictly covariantly inside the left-hand-side of strictly covariant function types, binding all of the freshly generated row variables at the top-level.It applies the auxiliary translation A * to function parameter types, similarly extending all record types appearing strictly covariantly in A with fresh row variables, and binding them all at the top-level.
We define four auxiliary functions for the translation.The functions , A and , A * are used to generate fresh row variables.The , A takes a row variable and a type A, and generates a sequence of row variables based on with the same length of row variables bound by A .The function , A * does the same thing for A * .The functions A, and A, * instantiate polymorphic types, simulating term-level type application.As we discussed in Section 5.2, these functions actually break the compositionality of the type translation, because they must inspect the concrete structure of A .However, we only use the type translation in the theorem and proof; the compositionality of the erasure translation itself remains intact.
After giving the type and environment translation, we aim for a weak type preservation theorem which allows the translated terms to have subtypes of the original terms, because the erasure translation ignores all upcasts.As we have row variables in 1 , the types of translated terms may contain extra row variables in strictly covariant positions.We need to define an auxiliary subtype  relation which only considers row variables.
Finally, we have the following weak type preservation theorem.T 6.2 (W T P ).Every well-typed full 2 term Δ; Γ ⊢ M : A is translated to a well-typed 1 term Δ; Γ ⊢ M : for some A ′ A and A ′ .
The proof makes use of afull 2 , an algorithmic variant of the type system of full 2 which combines T-App and T-Upcast into one rule T-AppSub, and removes all explicit upcasts in terms.
It is standard that afull 2 is sound and complete with respect to full 2 [Pierce 2002].Immediately, we have that Δ; Γ ⊢ M : A in full 2 implies Δ; Γ ⊢ M : A ′ in afull 2 for some A ′ A, where M is defined as M with all upcasts erased.Thus, we only need to prove that Δ; Γ ⊢ M : A in afull 2 implies Δ; Γ ⊢ M : for some A in 1 .The remaining proof can be done by induction on the typing derivations in afull 2 , where the most non-trivial case is the T-AppSub rule.The core idea is to use instantiation in 1 to simulate the subtyping relation A ′ A in the T-AppSub rule.This is possible because the source language afull 2 is restricted to have rank-2 records, which implies that A → B is translated to a polymorphic type where the record types in parameters are open and can be extended to simulate the subtyping relation.The full proof can be found in Appendix D.1.
So far, we have formalised the erasure translation from full 2 to 1 .As shown in Section 2.4, we have three other results.For records, we have another erasure translation from full 1 , the fragment of full where types are restricted to have rank-1 records, to 1 with rank-1 presence polymorphism.Similarly, for variants, we formally define a type A to have rank-n variants, if the predicate Ω n (A) defined as follows holds.
We also have two erasure translations from full They all use the same idea to let type inference infer row/presence-polymorphic types for terms involving records/variants, and use instantiation to automatically simulate subtyping.We omit the metatheory of these three results as they are similar to what we have seen for the encoding of full 2 in 1 .
The requirement of rank-1 polymorphism and Hindley-Milner type inference for target languages is not mandatory; target languages can support more advanced type inference for higherrank polymorphism like FreezeML [Emrich et al. 2020], as long as no type annotation is needed to infer rank-1 polymorphic types.One might hope to also relax the ℧ 2 (−) restriction in full 2 via enabling higher-rank polymorphism.However, at least the erasure translation do not work anymore.For instance, consider the functions id = x ℓ:Int .xand const = x ℓ:Int .ℓ = 1 with the same type ℓ : Int → ℓ : Int .Type inference would give id the type ∀ Row {ℓ } .ℓ : Int; → ℓ : Int; , and const the type ∀ Row {ℓ } .ℓ : Int; → ℓ : Int .For a second-order function of type ( ℓ : Int → ℓ : Int ) → A, we cannot give a type to the parameter of the function after translation which can be unified with the types of both id and const .We leave it to future work to explore whether there exist other translations making use of type inference for higher-rank polymorphism.

DISCUSSION
We have now explored a range of encodings of structural subtyping for variants and records as parametric polymorphism under different conditions.These encodings and non-existence results capture the extent to which row and presence polymorphism can simulate structural subtyping and crystallise longstanding folklore and informal intuitions.In the remainder of this section we briefly discuss record extensions and default cases (Section 7.1), combining subtyping and polymorphism (Section 7.2), related work (Section 7.3) and conclusions and future work (Section 7.4).

Record Extensions and Default Cases
Two important extensions to row and presence polymorphism are record extensions [Rémy 1994], and its dual, default cases [Blume et al. 2006].These operations provide extra expressiveness beyond structural subtyping.For example, with default cases, we can give a default age 42 to the function getAge in Section 2.1, and then apply it to variants with arbitrary constructors.

Combining Subtyping and Polymorphism
Though row and presence polymorphism can simulate subtyping well and support expressive extensions like record extension and default cases, it can still be beneficial to allow both subtyping and polymorphism together in the same language.For example, the OCaml programming language combines row and presence polymorphism with subtyping.Row and presence variables are hidden in its core language.It supports both polymorphic variants and polymorphic objects (a variation on polymorphic records) as well as explicit upcast for closed variants and records.Our results give a rationalisation for why OCaml supports subtyping in addition to row polymorphism.Row polymorphism simply is not expressive enough to give a local encoding of unrestricted structural subtyping, even though OCaml indirectly supports full first-class polymorphism.
Bounded quantification [Cardelli et al. 1994;Cardelli and Wegner 1985] extends system F with subtyping by introducing subtyping bounds to type variables.There is also much work on the type inference for both polymorphism and subtyping based on collecting, solving, and simplifying constraints [Pottier 1998[Pottier , 2001;;Trifonov and Smith 1996].Algebraic subtyping [Dolan 2016;Dolan and Mycroft 2017] combines subtyping and parametric polymorphism, offering compact principal types and decidable subsumption checking.MLstruct [Parreaux and Chau 2022] extends algebraic subtyping with intersection and union types, giving rise to another alternative to row polymorphism.

Related Work
Row types.Wand [1987] first introduced rows and row polymorphism.There are many further papers on row types, which take a variety of approaches, particularly focusing on extensible records.Harper and Pierce [1990] extended System F with constrained quantification, where predicates lacks L and has L are used to indicate the presence and absence of labels in row variables.Gaster and Jones [1996] and Gaster [1998] explored a calculus with a similar lacks predicate based on qualified types.Rémy [1989] introduced the concept of presence types and polymorphism, and Rémy [1994] combines row and presence polymorphism.Leijen [2005] proposed a variation on row polymorphism with support for scoped labels.Pottier and Rémy [2004] considered type inference for row and presence polymorphism in HM(X).Morris and McKinna [2019] introduced R , an algebraic foundation for row typing via a rather general language with two predicates representing the containment and combination of rows.It is parametric over a row theory which enables it to express different styles of row types (including Wand and Rémy's style and Leijen's style).
Row polymorphism vs structural subtyping.Wand [1987] compared his calculus with row polymorphism (similar to ) and showed that they cannot be encoded in each other by examples.Pottier [1998] conveyed the intuition that row polymorphism can lessen the need for subtyping to some extent, but there are still situations where subtyping are necessary, e.g., the reuse of -bound variables which cannot be polymorphic given only rank-1 polymorphism.
Disjoint polymorphism.Disjoint intersection types [d. S. Oliveira et al. 2016] generalise record types.Record concatenation and restriction [Cardelli and Mitchell 1991] are replaced by a merge operator [Dunfield 2014] and a type difference operator [Xu et al. 2023], respectively.Parametric polymorphism of disjoint intersection types is supported via disjoint polymorphism [Alpuim et al. 2017] where type variables are associated with disjointness constraints.Similarly to our work, Xie et al. [2020] formally prove that both row polymorphism and bounded quantification of record types can be encoded in terms of disjoint polymorphism.

Conclusion and Future Work
We carried out a formal and systematic study of the encoding of structural subtyping as parametric polymorphism.To better reveal the relative expressive power of these two type system features, we introduced the notion of type-only translations to avoid the influence of non-trivial term reconstruction.We gave type-only translations from various calculi with subtyping to calculi with different kinds of polymorphism and proved their correctness; we also proved a series of non-existence results.Our results provide a precise characterisation of the long-standing folklore intuition that row polymorphism can often replace subtyping.Additionally, they offer insight into the trade-offs between subtyping and polymorphism in the design of programming languages.
In future, we would like to explore whether it might be possible to extend our encodings relying on type inference to systems supporting higher-rank polymorphism, such as FreezeML [Emrich et al. 2020].We would also like to consider other styles of row typing such as those based on scoped labels [Leijen 2005] and R [Morris and McKinna 2019].In addition to variant and record types, row types are also the foundation for various effect type systems, e.g. for effect handlers [Hillerström and Lindley 2016;Leijen 2017].It would be interesting to investigate to what extent our approach can be applied to effect typing.Aside from studying the relationship between subtyping and row and presence polymorphism we would also like to study the ergonomics of these programming language features in practice, especially their compatibility with others such as algebraic data types.

A MORE CALCULI
In this section, we elaborate on calculi that are not fully detailed in the body of the paper.

A.1 A Calculus with Row Polymorphic Records
The extensions to the syntax, static semantics, and dynamic semantics of for a calculus with row polymorphic records are shown in Figure 9. Actually, they are exactly the same as the extensions to [ ] for [ ] in Figure 4.

Syntax
Type ∋ A :: The extensions to the syntax, static semantics, and dynamic semantics for 1 , a calculus with records and rank-1 row polymorphism are shown in Figure 11.For the type syntax, we introduce row variables and type schemes.For the term syntax, we drop the type annotation on abstractions, and add the let syntax for polymorphism.We only give the declarative typing rules, as the syntax-directed typing rules and type inference are just standard [Damas and Milner 1982].Notice that we do not introduce type variables for values in type schemes for simplicity.The lack of principal types is fine here as we are working with declarative typing rules.It is easy to regain principal types by adding value type variables.

B PROOFS OF ENCODINGS IN SECTION 4
In this section, we show the proofs of type preservation and operational correspondence for all the four translations in Section 4.

P
. By straightforward induction on M.
Our goal follows from IH and definition of substitution.(ℓ M ′ ) A Our goal follows from IH and definition of substitution.case M ′ {ℓ i x i ↦ → N i } i Our goal follows from IH and definition of substitution.M ′ ⊲ A By IH and definition of substitution, we have (M

P
. By straightforward induction on typing derivations.

T-Var
Our goal follows from x = x and T-Var.

T-Lam
Our goal follows from IH and T-Lam.

Syntax
TypeScheme ∋ :: : First, we prove the base case that the whole term M is reduced, i.e.M ⊲ N implies M N .The proof proceeds by case analysis on the reduction relation: where the last equation follows from Lemma B.1.

-Case
We have case M Similar to the -Lam case.
(ℓ M ′ ) [R] By IH and definition of substitution, we have By an equational reasoning similar to the case of (ℓ M ′ ) [R] .M ′ ⊲ A By an equational reasoning similar to the case of (ℓ M ′ ) [R] .
: First, we prove the base case where the whole term M is reduced, i.e.M N implies M ?N , and M ⊲ N implies M N .The proof proceeds by case analysis on the reduction relation: where the last equation follows from Lemma B.2.

-Case
We have case (ℓ j M j ) [R] . Then, we prove the full theorem by induction on M. We only need to prove the case where reduction happens in sub-terms of M. x No reduction.
By the definition of translation, we know that N

P
. By straightforward induction on M.
Our goal follows from IH and definition of substitution.ℓ i = M i i Our goal follows from IH and definition of substitution.M ′ .ℓ Our goal follows from IH and definition of substitution.M ′ ⊲ A By IH and definition of substitution, we have

P
. By straightforward induction on M. We only need to consider cases that are different from the proof of Lemma B.3. ℓ i = M i i By IH and definition of substitution, we have By an equational reasoning similar to the case of ℓ i = M i i .M ′ ⊲ A By an equational reasoning similar to the case of ℓ i = M i i .• The presence type application M ′ @ P 1 is reduced by -PreLam.Because the toplevel constructor of M ′ should be type abstraction, there are two cases.Proceed by case analysis on M ′ .
-M ′ = ℓ i = M ℓ i i .We can reduce all presence type application of P i .By (3) and (4), we have M * ℓ ′ j = M ℓ ′ j j .Our goal follows from setting N to ℓ ′ j = M ℓ ′ j j and M ⊲ N .

C ENCODINGS, PROOFS AND DEFINITIONS IN SECTION 5
In this section, we provide the encodings, proofs, and definitions missing from Section 5.  -Tannen et al. 1991;Pierce 2002] is formalised as follows.

C.1 Local Term-Involved Encoding of full
In addition to the erasure semantics, the other style of dynamic semantics of full is given by extending the operational semantics rules with the following four upcast rules.

⊲-Var
M ⊲ ⊲ M ⊲-Lam We show that there is a correspondence between these two styles of dynamic semantics of full .We first give a preorder M ⊑ N on terms of the untyped [ ] which allows records in M to contain more elements than those in N , because the erasure semantics does not truly perform upcasts.The full definition is shown in Figure 12.
The correspondence is given by the following theorem.To prove it, we need two lemmas.

D THE PROOF IN SECTION 6
In this section, we spell out the proofs that are missing from Section 6. D.1 Proof of encoding full 2 using 1 T 6.2 (W T P ).Every well-typed full 2 term Δ; Γ ⊢ M : A is translated to a well-typed 1 term Δ; Γ ⊢ M : for some A ′ A and A ′ .

P .
As shown in Section 6, we only need to prove that Δ; Γ ⊢ M : A in afull implies Δ; Γ ⊢ M : for some A in 1 .We proceed by induction on the typing derivations in afull .

T-Var
Our goal follows directly from the definition of translations.

Fig. 1 .
Fig. 1.Overview of translations and non-existence results covered in the paper.
The kinding and typing rules for polymorphism (K-PreAll, T-PreLam, T-PreApp) are the standard ones for System F specialised to presence types.The first three new kinding rules K-Absent, K-Present, and K-PreVar handle presence types directly.They assign kind Pre to absent, present, and polymorphic presence annotation respectively.The kinding rule K-ExtendRow is extended with a new kinding judgement to check P is a presence type.The typing rules for records, T-Record, and projections, T-Project, are updated to accommodate the presence annotations on labels.The typing rule for record introduction, T-Record, is changed such that the type of each component coincides with the annotation.The projection rule, T-Project, is changed such that the ℓ component must be present in the record row.Dynamic Semantics.The new rewrite rule -PreLam is the standard rule for System F, but specialised to presence types.As with [ ] we use the notation to distinguish it from other Syntax Kind ∋ K ::= . . .| Pre Type ∋ A ::= . . .| ∀ .A Row ∋ R ::= . . .| ℓ P : A; R Presence ∋ P ::

Fig. 5 .
Fig. 5. Extensions and modifications to with presence polymorphism .Highlighted parts replace the old ones in , rather than extensions.
Every well-typed term Δ; Γ ⊢ M : A is translated to a well-typed term Δ ; Γ ⊢ M : A .One upcast or -reduction in corresponds to a sequence of -reductions in .
Every well-typed term Δ; Γ ⊢ M : A is translated to a well-typed term Δ ; Γ ⊢ M : A .

T 4. 9 .
There exists no global type-only encoding of in , and no global type-only encoding of [ ] in [ ] .

Fig. 6 .
Fig. 6.Full subtyping rules of full [ ] of [ ] and with full subtyping, in [ ] , the combination of [ ] and .Figure 6 shows the standard full subtyping rules of full [ ] , which transforms subtyping relations A B into coercion functions A B .Writing translations in the form of coercion functions ensures compositionality.The translation is standard and shown in Appendix C.1.For instance, the full subtyping relation in Section 2.5 is translated to Name : String; Child : Name : String; Age : Int Child : Name : String = ( x. Child = Name : String; Age : Int Name : String x.Child ) = x.Child = ( x. Name = x.Name ) x.Child ) * x.Child = Name = x.Child.Name . One might worry that Theorem 5.3 contradicts the duality between records and variants, especially in light ofBlume et al. [2006]'s translation from variants with default cases to records with Proc.ACM Program.Lang., Vol. 7, No. OOPSLA2, Article 260.Publication date: October 2023.
The translation − from full 2 to 1 satisfies the equation erase(M) = erase( M ) for any well-typed term M in full 2 .P. By definition of erase(−) and − .

Fig. 8 .
Fig. 8.The translations of types and environments from full 2 to 1 .

Fig. 11 .
Fig. 11.Extensions and modifications to for a calculus with rank-1 row polymorphism 1 .Highlighted parts replace the old ones in , rather than Every well-typed [ ] term Δ; Γ ⊢ M : A is translated to a well-typed [ ] term Δ ; Γ ⊢ M : A .P .By induction on typing derivations.T-Var Our goal follows from x = x.T-Lam Our goal follows from IH and T-Lam.T-App Our goal follows from IH and T-App.T-Inject By definition we have (l : A) ∈ R implies (l : A ) ∈ R for any .Then our goal follows from IH, T-Inject and T-RowLam.T-Case Our goal follows from IH and T-Case.T-Upcast The only subtyping relation in [ ] is for variant types.Given Δ; Γ ⊢ M [R] ⊲ [R ′ ] : [R ′ ], by Δ; Γ ⊢ M : [R] and IH we have Δ ; Γ ⊢ M : [R] .Then, by definition of translation and T-RowApp we have Δ Every well-typed term Δ; Γ ⊢ M : A is translated to a well-typed term Δ ; Γ ⊢ M : A .P .By straightforward induction on typing derivations.T-Var Our goal follows from x = x and T-Var.T-Lam Our goal follows from IH and T-Lam.T-App Our goal follows from IH and T-App.T-Record Our goal follows from IH and T-Record.T-Project Our goal follows from IH and T-Project.T-Upcast The only subtyping relation in is for record types.Given Δ; Γ ⊢ M ⊲ R ′ : R ′ and Δ; Γ ⊢ M : R , by IH we have Δ ; Γ ⊢ M : R .Then, supposing M = ℓ i = M ℓ i i and R ′ = (ℓ ′ j : A j ) j , by definition of translation, R R ′ and T-Record we have Δ ; Γ ⊢ ℓ ′ j = M ℓ ′ j j : R ′ .prove the base case that the whole term M is reduced, i.e.M ⊲ N implies M *N .The proof proceeds by case analysis on the reduction relation.-LamWehave( x A .M 1 ) M 2 M 1 [M 2 /x].Then, (1) ( x A .M 1 ) M 2 = ( x A .M 1 ) M 2 M 1 [ M 2 /x] = M 1 [M 2 /x] ,where the last equation follows from Lemma B.3.Proc.ACM Program.Lang., Vol. 7, No. OOPSLA2, Article 260.Publication date: October 2023.If Δ; Γ, x : A ⊢ M : B and Δ; Γ ⊢ N : A, then M [N /x] = M [ N /x].
Every well-typed term Δ; Γ ⊢ M : A is translated to a well-typed term Δ ; Γ ⊢ M : A .P .By induction on typing derivations.T-Var Our goal follows from x = x.T-Lam Our goal follows from IH and T-Lam.T-App Our goal follows from IH and T-App.T-Record Our goal follows from IH, T-Record and T-PreLam.T-Project Supposing M = M ′ .ℓj and Δ; Γ ⊢ M ′ : ℓ i : A i i , by definition of translation we have M ′ .ℓj = ( M ′ (P i ) i ).ℓ j where P j = •.IH on M ′ implies Δ ; Γ ⊢ M ′ : (∀ i ) i .ℓ i i : A i i .Our goal follows from T-PreApp and T-Project.T-Upcast The only subtyping relation in is for record types.Given Δ; Γ ⊢ M R ⊲ [R ′ ] : [R ′ ], by Δ; Γ ⊢ M : R and IH we have Δ ; Γ ⊢ M : R .Then, by definition of translation and T-RowApp we have Δ ; Γ ⊢ M R ⊲ R ′ : R ′ .
then there exists N such that N ′ * N and M ⊲◮ N .P .S: First, we prove the base case that the whole term M is reduced, i.e.M N implies M * N , and M ⊲ N implies M * N .The proof proceeds by case analysis on the reduction relation:-LamWe have( x A .M 1 ) M 2 M 1 [M 2 /x].Then, (1) ( x A .M 1 ) M 2 = ( x A .M 1 ) M 2 M 1 [ M 2 /x] = M 1 [M 2 /x] ,where the last equation follows from Lemma B.4. Proc.ACM Program.Lang., Vol. 7, No. OOPSLA2, Article 260.Publication date: October 2023.
We can apply getChildName to carol who has a daughter alice with the strictly covariant subtyping relation Name : String; Child : Name : String; Age : Int Child : Name : String .