Type-Preserving Compilation of Polymorphic Records
Prerequisites. Direct starred prerequisites: none. No later core chapter depends on this route.
Fix a decidable total order <𝗅𝖺𝖻 on a countable set of labels. Its running segment is 𝖠𝗀𝖾<𝗅𝖺𝖻𝖭𝖺𝗆𝖾<𝗅𝖺𝖻𝖮𝖿𝖿𝗂𝖼𝖾<𝗅𝖺𝖻𝖯𝗁𝗈𝗇𝖾. The selector 𝗇𝖺𝗆𝖾=𝜆𝑟.𝑟.𝖭𝖺𝗆𝖾 has one polymorphic record type. Applying it to the two records below needs different machine instructions. Write 𝑀⇝𝗋𝖾𝖼𝐶 when source term 𝑀 compiles to target term 𝐶. If records are vectors ordered by label, then {𝖭𝖺𝗆𝖾="𝙹𝚘𝚎",𝖮𝖿𝖿𝗂𝖼𝖾=403}⇝𝗋𝖾𝖼["𝙹𝚘𝚎",403],{𝖠𝗀𝖾=21,𝖭𝖺𝗆𝖾="𝙷𝚊𝚗𝚊𝚔𝚘",𝖯𝗁𝗈𝗇𝖾=7222}⇝𝗋𝖾𝖼[21,"𝙷𝚊𝚗𝚊𝚔𝚘",7222]. The first selection needs index 1 and the second needs index 2. Erasing the record type before choosing that number loses information; keeping a run-time label search loses constant-time selection. The type abstraction must therefore also abstract over the index required for that field.
Required fields do not determine a layout
Labels also have decidable equality. The order’s decision procedure returns, for any two labels, exactly one of less than, equal, or greater. Thus sorting a finite label list is an algorithm, not merely an existence argument. Base types are written 𝑏, source monotypes are written 𝜏, type variables are written 𝑡,𝑢, and result types are written 𝜐. The book-defined source calculus has 𝜏::=𝑏∣𝑡∣𝜏→𝜏∣{ℓ1:𝜏1,…,ℓ𝑛:𝜏𝑛},𝜎::=𝜏∣∀𝑡::𝑘.𝜎,𝑘::=𝖴∣{{ℓ1:𝜏1,…,ℓ𝑚:𝜏𝑚}}. Labels in either displayed finite field map are distinct. Their written order has no semantic force.
The calculus isolates index passing. A term is Church-style here when it writes every type abstraction Λ𝑡::𝑘.𝑀 and every type application 𝑀[𝜏] explicitly. The calculus omits polymorphic let, record modification, variants, and operation annotations. It is therefore a pedagogical simplification inspired by the record-compilation mechanism, not a literal syntactic fragment of Ohori’s source language.
In K-Rec, the map to the left of ⊇ is the complete record map, and the map to the right is the required-field map. The formation premise prevents an extra field from hiding an unbound type variable. Thus a record kind states required fields and their types; it does not state the size or order of the complete record.
A type substitution 𝑆 maps each variable in K to a type formed under K′. The pair (K′,𝑆)respectsK if and only if, for every 𝑡∈dom(K), K′⊢𝑆(𝑡)::𝑆(K(𝑡)). The substitution acts on field types inside record kinds as well as on ordinary types.
Replacing a required-field map 𝐹′ by a submap 𝐹⊆𝐹′ is a weakening of the record kind: it removes requirements without changing the complete record type.
Proof of Lemma 8.3 — Formation and record-kind weakening
Proof. For clause 1, invert the final kinding rule. Rule K-Type contains the required formation premise. Rule K-VarRec has subject 𝑡, and Ty-Var forms 𝑡. Rule K-Rec contains K⊢𝜏::𝖴; inversion of K-Type gives formation.
For clause 2, invert the record-kinding derivation. In K-VarRec, the map assigned to the variable contains 𝐹′ and therefore contains 𝐹, so a K-VarRec instance gives the result. In K-Rec, the complete record map contains 𝐹′ and 𝐹′⊇𝐹; transitivity of finite-map inclusion supplies the premise of a K-Rec instance. ◻
Proof. Induct on the formation derivation. The base case is unchanged. The arrow and record cases apply the induction hypotheses to their premises; record labels remain distinct because substitution changes only field types. In the variable case, respect gives K′⊢𝑆(𝑡)::𝑆(K(𝑡)), and clause 1 of lemma 8.3 extracts the required formation judgment. ◻
Proof. Induct on the displayed kinding derivation. In K-Type, lemma 8.4 gives formation of 𝑆(𝜏), so a K-Type instance applies. In K-VarRec, respect gives K′⊢𝑆(𝑡)::𝑆(K(𝑡)). The required field map is a submap of 𝑆(K(𝑡)), so clause 2 of lemma 8.3 gives the conclusion. In K-Rec, lemma 8.4 forms the substituted complete record. Substitution preserves labels and finite-map inclusion, so K-Rec applies. ◻
★☆☆ Let K′=∅ and let K={𝑎::𝖴,𝑟::{{𝖭𝖺𝗆𝖾:𝑎}}} and let 𝑆 send 𝑎 to 𝖲𝗍𝗋𝗂𝗇𝗀 and 𝑟 to {𝖠𝗀𝖾:𝖭𝖺𝗍,𝖭𝖺𝗆𝖾:𝖲𝗍𝗋𝗂𝗇𝗀}. Check every premise of definition 8.2, then derive the substituted record-kind judgment.
The kinding judgment proves that projection is legal, but it does not yet connect the proof to a term. The source system is fixed here so that every later compiler case has exactly one typing rule to follow.
Source terms are 𝑀::=𝑥∣𝑐𝑏∣𝜆𝑥:𝜏.𝑀∣𝑀𝑀∣Λ𝑡::𝑘.𝑀∣𝑀[𝜏]∣{ℓ1=𝑀1,…,ℓ𝑛=𝑀𝑛}∣𝑀.ℓ. Here 𝑐𝑏 is a constant whose base type is 𝑏. The record form is part of the raw syntax only when ℓ1,…,ℓ𝑛 are distinct. Thus a duplicate-label input is rejected before it becomes a source term. Terms are identified up to renaming of bound term and type variables. A type assignment T maps distinct term variables to source types formed under K.
The polymorphic selector is now explicit: 𝗇𝖺𝗆𝖾:=Λ𝑎::𝖴.Λ𝑟::{{𝖭𝖺𝗆𝖾:𝑎}}.𝜆𝑥:𝑟.𝑥.𝖭𝖺𝗆𝖾. Its complete type is ∀𝑎::𝖴.∀𝑟::{{𝖭𝖺𝗆𝖾:𝑎}}.𝑟→𝑎. The premise of R-Dot is supplied by K-VarRec; the two uses of R-TAbs then close the derivation.
If type arguments are erased before layout selection, both calls to 𝗇𝖺𝗆𝖾 become the same target function but demand different numeric indices. This is the obstruction that forces index passing.
A target with vectors and index abstraction
For a concrete record type 𝜏, let layout(𝜏) be its labels sorted by <𝗅𝖺𝖻. If ℓ occurs in that list, then posℓ(𝜏) is its one-based position. The operation is undefined on an abstract type variable. This chapter’s target uses one-based positions; the array target in chapter 4 uses zero-based offsets. Thus the first component has position 1 here.
For a concrete record monotype, a label is required when it occurs in the record. For a type variable, its binding in the target kind assignment states the required labels. For any such label ℓ required by a monotype 𝜌, the index type𝗂𝖽𝗑(ℓ,𝜌) is a singleton type. When 𝜌 is concrete, its sole inhabitant is the positive numeral posℓ(𝜌). When 𝜌 is abstract, an index variable bound at that singleton type supplies its inhabitant.
Target monotypes 𝜌, target types 𝜔, and target kinds ℎ are generated recursively by 𝜌::=𝑏∣𝑡∣𝜌→𝜌∣{ℓ1:𝜌1,…,ℓ𝑛:𝜌𝑛},𝜔::=𝜌∣∀𝑡::ℎ.𝜔∣𝗂𝖽𝗑(ℓ,𝜌)⇒𝗂𝜔,ℎ::=𝖴∣{{ℓ1:𝜌1,…,ℓ𝑚:𝜌𝑚}}. Labels in target record monotypes and target record kinds are distinct. A target kind assignment H is an ordered list 𝑡::ℎ. If a binding 𝑡::ℎ has prefix H′, then H′⊢𝖵ℎ𝗄𝗂𝗇𝖽. Target-kind formation is generated by
H⊢𝖵𝖴𝗄𝗂𝗇𝖽
VK-U
H⊢𝖵𝜌𝑖𝗍𝗒𝗉𝖾(1≤𝑖≤𝑚)ℓ1,…,ℓ𝑚aredistinct
H⊢𝖵{{ℓ𝑖:𝜌𝑖}}𝑚𝑖=1𝗄𝗂𝗇𝖽
VK-Rec
The judgment H⊢𝖵𝜌𝗍𝗒𝗉𝖾 forms base types, variables bound in H, arrows, and distinct-label records. The judgment H⊢𝖵𝜌::ℎ assigns 𝖴 to a formed monotype, assigns a variable every record kind licensed by its binding, and assigns a concrete record every required-field submap that it contains. These are exactly the rules Ty-Base–Ty-Rec and K-Type–K-Rec from definition 8.1, under the replacements K,𝜏,𝑘↦H,𝜌,ℎ and ⊢↦⊢𝖵. Target-type formation adds exactly the rules
H⊢𝖵𝜌𝗍𝗒𝗉𝖾
H⊢𝖵𝜌𝗍𝖺𝗋𝗀𝖾𝗍𝗍𝗒𝗉𝖾
VT-Mono
H⊢𝖵ℎ𝗄𝗂𝗇𝖽H,𝑡::ℎ⊢𝖵𝜔𝗍𝖺𝗋𝗀𝖾𝗍𝗍𝗒𝗉𝖾
H⊢𝖵∀𝑡::ℎ.𝜔𝗍𝖺𝗋𝗀𝖾𝗍𝗍𝗒𝗉𝖾
VT-All
H⊢𝖵𝜌::{{ℓ:𝜌′}}H⊢𝖵𝜔𝗍𝖺𝗋𝗀𝖾𝗍𝗍𝗒𝗉𝖾
H⊢𝖵𝗂𝖽𝗑(ℓ,𝜌)⇒𝗂𝜔𝗍𝖺𝗋𝗀𝖾𝗍𝗍𝗒𝗉𝖾
VT-IArrow
An index arrow belongs only to the target type syntax; it is not a source function type.
A source index assignmentL maps index variables 𝐼 to required pairs (ℓ,𝜏). A pair is bookkeeping data for an index certificate, not a source type. A target index assignment I maps index variables to the target singleton types 𝗂𝖽𝗑(ℓ,𝜌).
For every pair (𝑡,ℓ) fix an index variable 𝐼𝑡,ℓ such that 𝐼𝑡,ℓ=𝐼𝑢,ℓ′ if and only if 𝑡=𝑢 and ℓ=ℓ′. This is a globally injective allocator. If K(𝑡)={{ℓ1:𝜏1,…,ℓ𝑚:𝜏𝑚}}, define LK,𝑡={𝐼𝑡,ℓ𝑖↦(ℓ𝑖,𝑡)∣1≤𝑖≤𝑚}. Write LK for the union of these assignments over the record-kinded variables of K. Global injectivity makes every such union a finite map and makes the extension for a fresh 𝑡 disjoint from the ambient assignment.
Call 𝑆 a ground substitution when every image 𝑆(𝑡) is a closed monotype. Let 𝑆 be ground and respect K. The numeral substitution𝜈𝑆 has domain dom(LK) and is defined by 𝜈𝑆(𝐼𝑡,ℓ):=posℓ(𝑆(𝑡)). It acts on target terms, not on target types. The type substitution 𝑆 and the numeral substitution 𝜈𝑆 are distinct operations.
If 𝑆 is ground and respects K, then equation 8.4 is defined for every binding of LK. Moreover, if K;LK⊢𝗂𝖱𝐼𝖼𝖾𝗋𝗍𝗂𝖿𝗂𝖾𝗌(ℓ,𝑡), then ∅;∅⊢𝗂𝖵𝜈𝑆(𝐼):𝗂𝖽𝗑(ℓ,𝑆(𝑡)).
Proof of Lemma 8.10 — Totality and typing of numeral substitution
Proof. Every binding has the form 𝐼𝑡,ℓ:𝗂𝖽𝗑(ℓ,𝑡) for a field required by K(𝑡). Because 𝑆 respects K, rule K-Rec or K-VarRec shows that 𝑆(𝑡) contains the ℓ field. Decidable sorting gives its unique positive position. Rule IV-Pos derives the displayed judgment. ◻
The central layout bookkeeping can be read in three columns. A row begins with a source label, points to its slot in the canonical target vector, and ends with the numeral inhabiting the corresponding index type:
source record
canonical slot
certified numeral
{𝖮𝖿𝖿𝗂𝖼𝖾,𝖭𝖺𝗆𝖾}: 𝖭𝖺𝗆𝖾
1↦"𝙹𝚘𝚎"
1:𝗂𝖽𝗑(𝖭𝖺𝗆𝖾,𝜏𝖩)
{𝖮𝖿𝖿𝗂𝖼𝖾,𝖭𝖺𝗆𝖾}: 𝖮𝖿𝖿𝗂𝖼𝖾
2↦403
2:𝗂𝖽𝗑(𝖮𝖿𝖿𝗂𝖼𝖾,𝜏𝖩)
{𝖯𝗁𝗈𝗇𝖾,𝖭𝖺𝗆𝖾,𝖠𝗀𝖾}: 𝖠𝗀𝖾
1↦21
1:𝗂𝖽𝗑(𝖠𝗀𝖾,𝜏𝖧)
{𝖯𝗁𝗈𝗇𝖾,𝖭𝖺𝗆𝖾,𝖠𝗀𝖾}: 𝖭𝖺𝗆𝖾
2↦"𝙷𝚊𝚗𝚊𝚔𝚘"
2:𝗂𝖽𝗑(𝖭𝖺𝗆𝖾,𝜏𝖧)
{𝖯𝗁𝗈𝗇𝖾,𝖭𝖺𝗆𝖾,𝖠𝗀𝖾}: 𝖯𝗁𝗈𝗇𝖾
3↦7222
3:𝗂𝖽𝗑(𝖯𝗁𝗈𝗇𝖾,𝜏𝖧)
Here 𝜏𝖩 and 𝜏𝖧 are the two concrete opening record types. Every row asserts the invariant 𝑖=posℓ(𝜏); the table illustrates that invariant and does not replace its proof.
Target terms are generated by 𝐶::=𝑥∣𝑐𝑏∣𝜆𝑥:𝜌.𝐶∣𝐶𝐶∣Λ𝑡::ℎ.𝐶∣𝐶[𝜌]∣[𝐶1,…,𝐶𝑛]∣𝐶⟨𝐽⟩∣𝜆𝗂𝐼.𝐶∣𝐶@𝐽. Angle brackets distinguish vector selection 𝐶⟨𝐽⟩ from type application 𝐶[𝜌].
An index assignment I is well formed under H if and only if each binding 𝐼:𝗂𝖽𝗑(ℓ,𝜌) has some 𝜌′ such that H⊢𝖵𝜌::{{ℓ:𝜌′}}. A term assignment U is well formed under H if and only if each binding 𝑥:𝜔 satisfies H⊢𝖵𝜔𝗍𝖺𝗋𝗀𝖾𝗍𝗍𝗒𝗉𝖾. The rules below take a target kind assignment H from definition 8.7, an index assignment I well formed under H, and a term assignment U well formed under H. The target judgment is H;I;U⊢𝖵𝐶:𝜔. Its complete non-record rules are
The semantic theorem needs the exact compatible closure, not only the two target-specific roots. Source values and target values are 𝑣::=𝑐𝑏∣𝜆𝑥:𝜏.𝑀∣Λ𝑡::𝑘.𝑀∣{ℓ𝑖=𝑣𝑖}𝑛𝑖=1,𝐴::=𝑐𝑏∣𝜆𝑥:𝜌.𝐶∣Λ𝑡::ℎ.𝐶∣[𝐴1,…,𝐴𝑛]∣𝜆𝗂𝐼.𝐶. The source evaluation contexts 𝐸𝖱 and target evaluation contexts 𝐸𝖵 evaluate applications and aggregate components from left to right: 𝐸𝖱::=[]∣𝐸𝖱𝑀∣𝑣𝐸𝖱∣𝐸𝖱[𝜏]∣𝐸𝖱.ℓ∣{ℓ𝑗=𝑣𝑗}𝑗<𝑖,ℓ𝑖=𝐸𝖱,{ℓ𝑗=𝑀𝑗}𝑖<𝑗,𝐸𝖵::=[]∣𝐸𝖵𝐶∣𝐴𝐸𝖵∣𝐸𝖵[𝜌]∣𝐸𝖵⟨𝑖⟩∣𝐸𝖵@𝑖∣[𝐴1,…,𝐴𝑖−1,𝐸𝖵,𝐶𝑖+1,…,𝐶𝑛]. The comma-separated record-context line denotes the record whose fields before 𝑖 are values, whose 𝑖th field is the hole, and whose later fields are unevaluated. The root contractions are (𝜆𝑥:𝜏.𝑀)𝑣⇝0𝑀[𝑣/𝑥],(Λ𝑡::𝑘.𝑀)[𝜏]⇝0𝑀[𝜏/𝑡],{ℓ𝑖=𝑣𝑖}𝑛𝑖=1.ℓ𝑗⇝0𝑣𝑗(1≤𝑗≤𝑛), and (𝜆𝑥:𝜌.𝐶)𝐴⇝0𝐶[𝐴/𝑥],(Λ𝑡::ℎ.𝐶)[𝜌]⇝0𝐶[𝜌/𝑡],[𝐴1,…,𝐴𝑛]⟨𝑖⟩⇝0𝐴𝑖(1≤𝑖≤𝑛),(𝜆𝗂𝐼.𝐶)@𝑖⇝0𝐶[𝑖/𝐼]. The relations ⟶𝖱 and ⟶𝖵 are the compatible closures under their respective contexts. Their reflexive–transitive closures are ⟶∗𝖱 and ⟶∗𝖵. Write 𝑀⇓𝖱𝑣 when 𝑀⟶∗𝖱𝑣, and write 𝑀⇑𝖱 when there is an infinite ⟶𝖱 sequence from 𝑀; use the corresponding 𝖵 notation for target terms.
Both one-step relations are deterministic. Let 𝑊 be any relation on closed source and target values, and relate closed terms when both diverge or when they terminate at a pair in 𝑊. If 𝑀⟶∗𝖱𝑀′ and 𝐶⟶∗𝖵𝐶′, then (𝑀,𝐶) belongs to this lifting of 𝑊 if and only if (𝑀′,𝐶′) does.
Proof of Lemma 8.12 — Determinism and evaluation-prefix closure
Proof. Each nonvalue has at most one decomposition into a displayed evaluation context and a displayed root redex: application and aggregate contexts choose the leftmost nonvalue, while type application, projection, selection, and index application evaluate only their operator. The raw-syntax distinctness condition gives exactly one field with the projected label, and a numeric vector position names exactly one component. Every root therefore has one contractum, so both step relations are deterministic.
For prefix closure, a finite prefix cannot change whether a deterministic sequence is infinite. If evaluation terminates, deleting or adding a finite prefix preserves its unique terminal value. Hence the two terms diverge together before the prefixes exactly when they do afterward, and their terminal pair belongs to 𝑊 before the prefixes exactly when it does afterward. ◻
★☆☆ Using the fixed running label order, compute the two layouts from the chapter opening and the position of 𝖭𝖺𝗆𝖾 in each. Then type both selections with V-Nth and perform both vector root contractions from equation 8.6.
The translation of a quantified type records the index arguments required by its kind. Before translating a record kind, enumerate its finite field map in increasing label order; hence the indices 1,…,𝑚 below are canonical and do not depend on the source presentation order. Write 𝑘={{ℓ𝑖:𝜏𝑖}}𝑚𝑖=1 and 𝑘∗={{ℓ𝑖:𝜏∗𝑖}}𝑚𝑖=1. Define 𝑏∗=𝑏,𝑡∗=𝑡,(𝜏1→𝜏2)∗=𝜏∗1→𝜏∗2,({ℓ𝑖:𝜏𝑖}𝑛𝑖=1)∗={ℓ𝜋(𝑗):𝜏∗𝜋(𝑗)}𝑛𝑗=1,ℓ𝜋(1)<𝗅𝖺𝖻⋯<𝗅𝖺𝖻ℓ𝜋(𝑛),(∀𝑡::𝖴.𝜎)∗=∀𝑡::𝖴.𝜎∗,(∀𝑡::𝑘.𝜎)∗=∀𝑡::𝑘∗.𝗂𝖽𝗑(ℓ1,𝑡)⇒𝗂⋯⇒𝗂𝗂𝖽𝗑(ℓ𝑚,𝑡)⇒𝗂𝜎∗. In the record-type line, the superscript star applies to the whole type on the left; labels are not translated. Translation acts pointwise on contexts: ∅∗=∅,(K,𝑡::𝑘)∗=K∗,𝑡::𝑘∗,(T,𝑥:𝜎)∗=T∗,𝑥:𝜎∗,(L,𝐼↦(ℓ,𝜏))∗=L∗,𝐼:𝗂𝖽𝗑(ℓ,𝜏∗). Thus K∗ is a target kind assignment, T∗ is a target term assignment, and L∗ is a target index assignment.
For every source monotype 𝜏, the type 𝜏∗ has the same finite record maps as 𝜏 and presents every map in canonical label order. The following judgments and equations hold.
If K⊢𝜏𝗍𝗒𝗉𝖾, then K∗⊢𝖵𝜏∗𝗍𝗒𝗉𝖾.
If K⊢𝜏::𝑘, then K∗⊢𝖵𝜏∗::𝑘∗.
If K;L⊢𝗂𝖱𝐽𝖼𝖾𝗋𝗍𝗂𝖿𝗂𝖾𝗌(ℓ,𝜏), then K∗;L∗⊢𝗂𝖵𝐽:𝗂𝖽𝗑(ℓ,𝜏∗).
(𝜎[𝜏/𝑡])∗=𝜎∗[𝜏∗/𝑡], (LK)∗=LK∗, and ftv(T∗)=ftv(T).
If K is a well-formed source kind assignment, then K∗ is a well-formed target kind assignment.
Proof of Lemma 8.13 — Canonical translation and index transport
Proof. Prove clauses 1 and 2 simultaneously by induction on source formation and kinding. Base and variable translations are identities. Arrow premises use the two formation induction hypotheses. In a record premise, decidable sorting changes neither labels nor their associated translated field types, so it preserves formation and finite-map inclusion. These are exactly the target instances of Ty-Rec, K-VarRec, and K-Rec.
For clause 3, invert the source index judgment. Rule IR-Var becomes IV-Var by the pointwise definition of L∗. Rule IR-Pos uses clause 2; translation preserves the label set and hence the sorted position, so IV-Pos applies with the same numeral.
The substitution equation follows by induction on 𝜎. At a record type, substitution changes field types but not labels, so both sides use the same sorting permutation. The canonical-assignment equation follows from the pairwise definition of 𝐼𝑡,ℓ, and the free-variable equation follows by induction on every type in T. Finally, induction on the ordered bindings of K uses clause 1 on every field type of the translated kind and then applies VK-U or VK-Rec. ◻
Compilation is a derivation-directed judgment K;L;T⊢𝑀⇝𝗋𝖾𝖼𝐶:𝜎. This judgment is defined only when L=LK. Consequently, extending K by a fresh record-kinded variable 𝑡 extends the compiler assignment by the disjoint map LK,𝑡 from equation 8.3. The pair-index allocator therefore makes lookup a function of (𝑡,ℓ) rather than a search among assignments that happen to share one index type. Its homomorphic term rules are
T(𝑥)=𝜎
K;L;T⊢𝑥⇝𝗋𝖾𝖼𝑥:𝜎
C-Var
K;L;T⊢𝑐𝑏⇝𝗋𝖾𝖼𝑐𝑏:𝑏
C-Const
K;L;T,𝑥:𝜏⊢𝑀⇝𝗋𝖾𝖼𝐶:𝜐
K;L;T⊢(𝜆𝑥:𝜏.𝑀)⇝𝗋𝖾𝖼(𝜆𝑥:𝜏∗.𝐶):𝜏→𝜐
C-Lam
K;L;T⊢𝑀1⇝𝗋𝖾𝖼𝐶1:𝜏→𝜐K;L;T⊢𝑀2⇝𝗋𝖾𝖼𝐶2:𝜏
K;L;T⊢𝑀1𝑀2⇝𝗋𝖾𝖼𝐶1𝐶2:𝜐
C-App
A record is sorted by the unique permutation 𝜋 satisfying ℓ𝜋(1)<𝗅𝖺𝖻⋯<𝗅𝖺𝖻ℓ𝜋(𝑛):
For a concrete 𝜏, the last premise chooses 𝐽=posℓ(𝜏); for 𝜏=𝑡, it chooses 𝐼𝑡,ℓ with LK(𝐼𝑡,ℓ)=(ℓ,𝑡) in the canonical map LK.
Let 𝑘={{ℓ𝑖:𝜏𝑖}}𝑚𝑖=1 be enumerated in canonical label order, let LK,𝑡={𝐼𝑡,ℓ𝑖↦(ℓ𝑖,𝑡)}𝑚𝑖=1, and let 𝐽𝑖 be the index expression certified for ℓ𝑖 at an actual type 𝜏. The type-directed rules are
By C-TAbsU, C-TAbsRec, C-Lam, and C-Dot, the selector of equation 8.2 compiles to Λ𝑎::𝖴.Λ𝑟::{{𝖭𝖺𝗆𝖾:𝑎}}.𝜆𝗂𝐼𝑟,𝖭𝖺𝗆𝖾.𝜆𝑥:𝑟.𝑥⟨𝐼𝑟,𝖭𝖺𝗆𝖾⟩. The two ground instantiations of equation 8.9 pass 1 and 2, respectively. After those index applications, every field access is the constant-time vector operation in V-Nth; no labels remain in the selection instruction.
Suppose K⊢𝜏::{{ℓ:𝜐}}. Under LK, compilation determines an index expression 𝐽 with K;LK⊢𝗂𝖱𝐽𝖼𝖾𝗋𝗍𝗂𝖿𝗂𝖾𝗌(ℓ,𝜏). If 𝜏 is concrete, 𝐽 is its unique sorted position. If 𝜏=𝑡, 𝐽 is the unique index variable allocated to the ℓ field of 𝑡.
Proof. Invert the kinding derivation. If it ends in K-Rec, the finite-map inclusion places ℓ in the concrete record type. Sorting distinct labels gives one position, so the numeric index judgment holds. If it ends in K-VarRec, the kind assignment for 𝑡 contains the field. Equation 8.3 places exactly one corresponding binding in LK. ◻
Let K and T be well formed. If K;T⊢𝖱𝑀:𝜎, then there is a target term 𝐶 such that K;LK;T⊢𝑀⇝𝗋𝖾𝖼𝐶:𝜎. If 𝐷 satisfies the same judgment, then 𝐶 and 𝐷 are equal up to renaming of bound term, type, and index variables.
Proof of Theorem 8.16 — Total and deterministic compilation
Proof. Induct on the displayed source typing derivation. Rules R-Var and R-Const determine C-Var and C-Const. The induction hypothesis for the body of R-Lam determines its target body; C-Lam then determines the target annotation. The two induction hypotheses for R-App determine both target subterms, so C-App determines their application.
For R-Record, apply the induction hypothesis to every field. Decidable comparison computes one sorting permutation of the distinct labels, so C-Record exists and no second target vector order is possible. For R-Dot, lemma 8.15 gives exactly one 𝐽; C-Dot therefore exists and is determined.
For R-TAbs at a record kind, the pair-index allocator gives the unique extension LK,𝑡. It is disjoint from LK because 𝑡 is fresh. The induction hypothesis determines the body, and C-TAbsRec inserts the index binders in canonical label order. Renaming those binders accounts for the stated alpha-equivalence. At kind 𝖴, C-TAbsU adds no index binder. For R-TApp, lemma 8.15 determines each required actual index; C-TAppRec or C-TAppU then determines the target. These are all source rules. ◻
Proof of Theorem 8.17 — Type preservation of record compilation
Proof. Induct simultaneously on the source typing derivation and the matching compilation derivation. At each premise, translate all three assignments by equation 8.8; this is necessary because record types in kind, index, and term assignments are canonically reordered.
Variable and constant. Translation of the type assignment gives the target variable rule, and base constants retain their base type.
Term abstraction. The induction hypothesis under T,𝑥:𝜏1 gives 𝐶:𝜏∗2 under T∗,𝑥:𝜏∗1. Target abstraction derives 𝜆𝑥:𝜏∗1.𝐶:𝜏∗1→𝜏∗2.
Application. The two induction hypotheses give 𝐶1:𝜏∗1→𝜏∗2 and 𝐶2:𝜏∗1. Target application gives 𝐶1𝐶2:𝜏∗2.
Record. For every field, the induction hypothesis gives 𝐶𝑖:𝜏∗𝑖. The rule C-Record reorders the type entries by the same label permutation. Rule V-Vec therefore derives the canonically presented translated record type from equation 8.7.
Projection. The induction hypothesis gives 𝐶:𝜏∗. Clause 2 of lemma 8.13 translates the kinding premise to K∗⊢𝖵𝜏∗::{{ℓ:𝜐∗}}. The compilation premise certifies (ℓ,𝜏) for 𝐽 in the source index judgment; clause 3 transports it to K∗;(LK)∗⊢𝗂𝖵𝐽:𝗂𝖽𝗑(ℓ,𝜏∗). Rule V-Nth yields 𝐶⟨𝐽⟩:𝜐∗.
Type abstraction. First consider the record kind 𝑘={{ℓ𝑖:𝜏𝑖}}𝑚𝑖=1. The induction hypothesis under K,𝑡::𝑘 has target kind assignment K∗,𝑡::𝑘∗. The disjoint source extension translates as (LK,𝑡)∗={𝐼𝑡,ℓ𝑖:𝗂𝖽𝗑(ℓ𝑖,𝑡)∣1≤𝑖≤𝑚}. Thus the induction hypothesis uses the two disjoint target assignments (LK)∗,(LK,𝑡)∗. Repeated V-IAbs removes this disjoint suffix and derives the index-arrow body of equation 8.7. Since 𝑡 is fresh for K and the source premise has 𝑡∉ftv(T), clause 4 of lemma 8.13 gives 𝑡∉ftv((LK)∗,T∗). Rule V-TAbs therefore derives the outer ∀𝑡::𝑘∗. For 𝑘=𝖴, freshness of 𝑡 for K together with the source freshness premise for T gives the two target freshness conditions, so V-TAbs applies directly.
Type application. The induction hypothesis gives the translated universal type. Clause 2 of lemma 8.13 gives K∗⊢𝖵𝜏∗::𝑘∗, so V-TApp derives the translated universal body. For every record-kind field, the matching compilation premise certifies (ℓ𝑖,𝜏) for 𝐽𝑖 in the source index judgment. Clause 3 transports it to 𝐽𝑖:𝗂𝖽𝗑(ℓ𝑖,𝜏∗) in the target index judgment. Applying V-IApp𝑚 times gives 𝜎∗[𝜏∗/𝑡], equal to (𝜎[𝜏/𝑡])∗ by structural induction on 𝜎. No index applications occur for 𝖴.
★★☆ Instantiate equation 8.9 at 𝑎=𝖲𝗍𝗋𝗂𝗇𝗀 and 𝑟={𝖠𝗀𝖾:𝖭𝖺𝗍,𝖭𝖺𝗆𝖾:𝖲𝗍𝗋𝗂𝗇𝗀,𝖯𝗁𝗈𝗇𝖾:𝖭𝖺𝗍}. Give the target typing derivation for the index application with 𝐽=2, then derive the type of its application to [21,"𝙷𝚊𝚗𝚊𝚔𝚘",7222].
Type preservation says where compiled terms live. It does not yet say that vector position 2 denotes the source field named 𝖭𝖺𝗆𝖾. Define a relation that follows the canonical layout.
Let 𝑆 map every free type variable under consideration to a closed monotype. An 𝑆-indexed relation environment 𝜒 maps each such variable 𝑡 to a relation between closed source values of type 𝑆(𝑡) and closed target values of type 𝑆(𝑡)∗. Define the value relation V𝑆,𝜒𝗋𝖾𝖼(𝜎) and term relation E𝑆,𝜒𝗋𝖾𝖼(𝜎) by structural induction on the open type 𝜎.
The variable and base clauses are V𝑆,𝜒𝗋𝖾𝖼(𝑡)=𝜒(𝑡),V𝑆,𝜒𝗋𝖾𝖼(𝑏)={(𝑐𝑏,𝑐𝑏)∣𝑐𝑏isaconstantofbasetype𝑏}. The arrow clause is (𝑣,𝐴)∈V𝑆,𝜒𝗋𝖾𝖼(𝜏→𝜐)⟺∀(𝑎,𝐵)∈V𝑆,𝜒𝗋𝖾𝖼(𝜏).(𝑣𝑎,𝐴𝐵)∈E𝑆,𝜒𝗋𝖾𝖼(𝜐). For record values 𝑣𝑟={ℓ𝑖=𝑣𝑖}𝑛𝑖=1 and 𝐴𝑟=[𝐴𝜋(1),…,𝐴𝜋(𝑛)], the record clause is (𝑣𝑟,𝐴𝑟)∈V𝑆,𝜒𝗋𝖾𝖼({ℓ𝑖:𝜏𝑖}𝑛𝑖=1)⟺ℓ𝜋(1)<𝗅𝖺𝖻⋯<𝗅𝖺𝖻ℓ𝜋(𝑛)and(𝑣𝑖,𝐴𝑖)∈V𝑆,𝜒𝗋𝖾𝖼(𝜏𝑖)(1≤𝑖≤𝑛).
For the universal clause, let 𝜏 be a closed monotype satisfying ∅⊢𝜏::𝑆(𝑘). Put 𝑆′=𝑆[𝑡↦𝜏] and 𝜒′=𝜒[𝑡↦V∅,∅𝗋𝖾𝖼(𝜏)]. If 𝑆(𝑘)={{ℓ𝑖:𝑆(𝜏𝑖)}}𝑚𝑖=1 in canonical label order, let 𝑗𝑖=posℓ𝑖(𝜏); when 𝑆(𝑘)=𝖴, the list of 𝑗𝑖 is empty. Then (𝑣,𝐴)∈V𝑆,𝜒𝗋𝖾𝖼(∀𝑡::𝑘.𝜎)⟺foreverysuch𝜏,(𝑣[𝜏],𝐴[𝜏∗]@𝑗1⋯@𝑗𝑚)∈E𝑆′,𝜒′𝗋𝖾𝖼(𝜎). The recursive call is on the syntactic body 𝜎. The closing environment 𝑆′ makes every type in the binder kind closed; 𝜒′ records the relation chosen for the bound type.
Finally, (𝑀,𝐶)∈E𝑆,𝜒𝗋𝖾𝖼(𝜎) if and only if either 𝑀⇑𝖱 and 𝐶⇑𝖵, or there are values 𝑣,𝐴 such that 𝑀⇓𝖱𝑣,𝐶⇓𝖵𝐴,(𝑣,𝐴)∈V𝑆,𝜒𝗋𝖾𝖼(𝜎). For a closed 𝜎, write R𝜎𝗋𝖾𝖼 for E∅,∅𝗋𝖾𝖼(𝜎).
For the outer selector binder, choose 𝑆(𝑎)=𝖲𝗍𝗋𝗂𝗇𝗀. The inner binder kind is interpreted as 𝑆({{𝖭𝖺𝗆𝖾:𝑎}})={{𝖭𝖺𝗆𝖾:𝖲𝗍𝗋𝗂𝗇𝗀}}. Thus both opening record types are well-scoped choices for 𝑟; the type environment carries the ground type that a relation-only environment loses.
Let 𝑣𝖩,𝐴𝖩 and 𝑣𝖧,𝐴𝖧 be the two source-record/target-vector pairs in the opening calculation, and let 𝜏𝖩,𝜏𝖧 be their record types. The record clause computes to (𝑣𝖩,𝐴𝖩)∈V∅,∅𝗋𝖾𝖼(𝜏𝖩),(𝑣𝖧,𝐴𝖧)∈V∅,∅𝗋𝖾𝖼(𝜏𝖧). The pair with target [403,"𝙹𝚘𝚎"] is not in the first relation: its first component would have to relate the source 𝖭𝖺𝗆𝖾 string to the target office numeral. This near-nonexample tests the canonical permutation clause.
Let 𝑆 be ground, and define 𝜒𝑆(𝑡)=V∅,∅𝗋𝖾𝖼(𝑆(𝑡)). For every type 𝜎 formed under dom(𝑆), E𝑆,𝜒𝑆𝗋𝖾𝖼(𝜎)=R𝑆(𝜎)𝗋𝖾𝖼, and the analogous equality holds for the value relations. The term relation is closed under the following constructors:
related functions applied to related arguments yield related terms;
fieldwise related terms yield a related source record and canonically permuted target vector;
projection of ℓ and target selection at posℓ(𝑆(𝜏)) yield related terms; and
a universally related pair instantiated at a kind-respecting closed 𝜏 remains related after the target receives the positions required by the instantiated kind.
Proof. The two equalities follow by induction on 𝜎. The variable case is the definition of 𝜒𝑆. In the universal case, both sides quantify over ∅⊢𝜏::𝑆(𝑘) and extend by the same closed type and the same closed value relation.
For clause 1, split on the term relation for the function and then for the argument. Matched divergence makes both call-by-value applications diverge. Matched termination gives an arrow-related pair of function values and a value-related argument pair; the arrow clause gives the result, and lemma 8.12 adds the evaluation prefixes.
For clause 2, first suppose every related field pair terminates. The source record reaches its field values in written order, while the target vector reaches the related target values in canonical label order. The two orders may differ, but both evaluations are finite; after both finish, equation 8.11 relates the resulting aggregates. Otherwise, let ℓ𝑝 label the first divergent source field in presentation order, and let ℓ𝑞 label the first divergent target component in canonical order. Fieldwise relatedness makes the set of divergent labels the same on both sides. Every source field preceding the occurrence labelled ℓ𝑝 terminates, as does every target component preceding the occurrence labelled ℓ𝑞. The two aggregates therefore take possibly different finite prefixes and then both diverge. This proves clause 2 without claiming that source and target visit fields in the same order.
For clause 3, matched divergence is preserved by the projection contexts. In the terminating case, equation 8.11 places the ℓ components at the source field and canonical target position; the two roots in equation 8.5, equation 8.6 return those components. Clause 4 is exactly equation 8.12, followed by evaluation-prefix closure. ◻
Proof of Lemma 8.20 — Closing substitution equality
Proof. Induct on 𝜎. The variable case distinguishes 𝑡 from the variables in dom(𝑆); the remaining constructors apply the induction hypotheses to their immediate type components. ◻
Suppose K;T⊢𝖱𝑀:𝜎 and K;LK;T⊢𝑀⇝𝗋𝖾𝖼𝐶:𝜎. Let 𝑆 be a ground substitution respecting K, and put 𝜒𝑆(𝑡)=V∅,∅𝗋𝖾𝖼(𝑆(𝑡)). Suppose source and target value environments 𝜂 and 𝜁 satisfy (𝜂(𝑥),𝜁(𝑥))∈V𝑆,𝜒𝑆𝗋𝖾𝖼(𝜐)forevery𝑥:𝜐∈T. Then (𝑀[𝑆][𝜂],𝐶[𝑆][𝜈𝑆][𝜁])∈E𝑆,𝜒𝑆𝗋𝖾𝖼(𝜎). By lemma 8.19, the relation in equation 8.13 equals R𝑆(𝜎)𝗋𝖾𝖼.
Proof of Theorem 8.21 — Fundamental compilation relation
Proof. Induct simultaneously on the source typing derivation and the matching compilation derivation, keeping 𝑆,𝜂,𝜁 arbitrary. The decisive invariant is that 𝑆 closes kinds while the separate 𝜈𝑆 closes index variables.
Variable and constant. The environment hypothesis is exactly the variable conclusion. A base constant compiles to itself, so the base clause applies.
Term abstraction. Take any (𝑎,𝐴)∈V𝑆,𝜒𝑆𝗋𝖾𝖼(𝜏1). Extend 𝜂 by 𝑥↦𝑎 and 𝜁 by 𝑥↦𝐴. The induction hypothesis for the body gives the term relation at 𝜏2. The two term-beta roots and lemma 8.12 establish the arrow clause.
Application. The two induction hypotheses give the function and argument term relations. Clause 1 of lemma 8.19 gives the application relation.
Record. Each field induction hypothesis gives the corresponding term relation. Clause 2 of lemma 8.19 builds the labeled record and the target vector in the permutation computed by C-Record.
Projection. The induction hypothesis gives the record term relation. If compilation chose a concrete numeral, it is posℓ(𝑆(𝜏)). If it chose 𝐼𝑡,ℓ, lemma 8.10 gives 𝜈𝑆(𝐼𝑡,ℓ)=posℓ(𝑆(𝑡)). Clause 3 of lemma 8.19 therefore gives the projection result.
Type abstraction. Take a closed type 𝜏 with ∅⊢𝜏::𝑆(𝑘), and put 𝑆′=𝑆[𝑡↦𝜏]. Global injectivity gives the disjoint equation 𝜈𝑆′=𝜈𝑆,{𝐼𝑡,ℓ𝑖↦posℓ𝑖(𝜏)}𝑚𝑖=1. The induction hypothesis for the body under 𝑆′ gives the relation after the source type-beta root, target type-beta root, and the 𝑚 index-beta roots. This proves equation 8.12; for 𝑘=𝖴, 𝑚=0.
Type application. The induction hypothesis for the polymorphic term gives the universal term relation. Put ̂𝜏=𝑆(𝜏) and 𝑆′=𝑆[𝑡↦̂𝜏]. Kinding substitution gives ∅⊢̂𝜏::𝑆(𝑘). Clause 4 of lemma 8.19 applies the target to the positions inserted by C-TAppRec; lemma 8.10 identifies each closed 𝐽𝑖 with that position. Its conclusion is indexed by 𝑆′ and 𝜒𝑆′=𝜒𝑆[𝑡↦V∅,∅𝗋𝖾𝖼(̂𝜏)]. The type-application case therefore reduces to the equality of term relations E𝑆′,𝜒𝑆′𝗋𝖾𝖼(𝜎)𝑙𝑒𝑚𝑚𝑎8.19=R𝑆′(𝜎)𝗋𝖾𝖼𝑙𝑒𝑚𝑚𝑎8.20=R𝑆(𝜎[𝜏/𝑡])𝗋𝖾𝖼𝑙𝑒𝑚𝑚𝑎8.19=E𝑆,𝜒𝑆𝗋𝖾𝖼(𝜎[𝜏/𝑡]).
The listed cases cover every source and compilation rule, so equation 8.13 follows. ◻
Let 𝑀 be closed and well typed at a type 𝜎 generated by base types and finite records. If ∅;∅;∅⊢𝑀⇝𝗋𝖾𝖼𝐶:𝜎, then 𝑀 and 𝐶 terminate together. When they terminate, 𝐶 contains the same base values as 𝑀, arranged in the canonical layout of each record type.
Proof of Corollary 8.22 — Semantic correctness at observable types
Proof. Apply theorem 8.21 with empty environments and the identity ground substitution. Induction on the observable type turns the clauses of R𝜎𝗋𝖾𝖼 into equality of base constants and the stated canonical record permutation. ◻
★★☆ Prove the projection case of theorem 8.21 for the two records in the opening calculation, including both source contractions, both target contractions, and the two uses of the record-relation clause.
The local calculus omitted let-generalization, record modification, and variants so that the index-passing proof could be followed without an inference algorithm. Ohori’s theorem applies to a larger, fixed signature.
Let Λ𝗅𝖾𝗍,∙⊢K,T▹𝑀:𝜎 be a typing in Ohori’s explicitly typed, kinded source calculus. This source includes functions, kinded polymorphism, records, record modification, variants, case, and the paper’s explicit polymorphic-let form. If the paper’s algorithm gives C(LK,T∗,𝑀)=𝐶, then for every ground substitution 𝑆 respecting K and every pair of environments (𝜂1,𝜂2) related at 𝑆(T), (𝜂1(erase(𝑀)),𝜂2,𝑆(LK)(𝐶))∈R𝑆(𝜎). Here R is Ohori’s termination-sensitive logical relation, records are vectors, variants are numeric tags, and polymorphic record or variant operations receive explicit indices. This is Theorem 4.5.1 of the source at its stated source and implementation calculi [Oho95].
Proof of Theorem 8.23 — Ohori's compilation theorem
Imported proof. The proof in Ohori’s appendix is a logical-relations induction. Its projection mechanism matches the local relation. Its additional cases cover modification, tag selection, switches, polymorphic let, vacuous type-variable elimination, and interacting index assignments. The imported theorem owns those cases. They are not consequences of the book-defined record-only proof. ◻
The theorem targets the idealized implementation calculus in Ohori’s paper. The reported SML implementation did not include polymorphic variants and did not evaluate inside index abstractions according to that calculus. The modern poly-record-ml program is useful for inspectable layouts and generated code, but running it proves neither theorem 8.17, theorem 8.23. The row theory of chapter 4 also has different kinds, equations, and principality hypotheses; no inference theorem transfers between the two systems.
The source and target calculi, type translation, and general correctness signature are due to Ohori [Oho95]. The final seminar sequence is adapted to the representation calculations in the Régis-Gianas–Rémy examination [RGR11]; the implementation comparison uses the pinned program of [Uta19] only as executable corroboration.
Suggested first pass.
None of these problems is a prerequisite for later chapters. Begin with exercise 8.5, reconstruct the decisive proof case in exercise 8.6, and then implement exercise 8.9.
★★☆ Compile Λ𝑎::𝖴.Λ𝑟::{{𝖠𝗀𝖾:𝖭𝖺𝗍,𝖭𝖺𝗆𝖾:𝑎}}.𝜆𝑥:𝑟.{𝖭𝖺𝗆𝖾=𝑥.𝖭𝖺𝗆𝖾,𝖠𝗀𝖾=𝑥.𝖠𝗀𝖾}. Give its translated type, every inserted index abstraction, and its instantiation at {𝖭𝖺𝗆𝖾:𝖲𝗍𝗋𝗂𝗇𝗀,𝖯𝗁𝗈𝗇𝖾:𝖭𝖺𝗍,𝖠𝗀𝖾:𝖭𝖺𝗍}. Display the final two vector selections and their result layout.
★★☆ Reconstruct the record-kinded type-abstraction and type-application cases of theorem 8.17. State the induction hypothesis, prove that LK,𝑡 is disjoint from LK, derive every V-IAbs and V-IApp premise, and finish with the substitution equation from lemma 8.13.
★★☆ Consider a compiler that erases kinded type abstraction without inserting index abstraction. Compile the two calls to 𝗇𝖺𝗆𝖾 from the opening as far as this compiler permits. Prove that no one numeral can make both target selections return the 𝖭𝖺𝗆𝖾 field. State why a dynamic label search repairs behavior but fails the chapter’s constant-index target specification.
★★☆ Suppose a target vector is accompanied only by its length, not its source labels. Give two record types of equal length whose 𝖭𝖺𝗆𝖾 fields have different positions. State all field types and the two exact length witnesses. Prove that the vector and length do not determine the source projection. Identify the index-passing datum that restores the missing information.
★★★Practical project.polymorphic-record-compiler Implement the finite executable slice of C-Record, C-Dot, C-TAbsRec, and C-TAppRec from definition 8.14. Maintain the invariant that each layout contains every source label exactly once in <𝗅𝖺𝖻 order and that every emitted numeric selection is the position certified by that layout. Print the source field map, sorted layout, chosen index, and translated selection. The acceptance test must compile the two opening records to layouts [𝖭𝖺𝗆𝖾,𝖮𝖿𝖿𝗂𝖼𝖾] and [𝖠𝗀𝖾,𝖭𝖺𝗆𝖾,𝖯𝗁𝗈𝗇𝖾], emit indices 1 and 2 for 𝖭𝖺𝗆𝖾, return "Joe" and "Hanako" after vector selection, and reject selection of a missing 𝖯𝗁𝗈𝗇𝖾 field from the first layout. The rejection must occur before target execution. Also reject a source record containing the same label twice before constructing its layout. Finally, compile the polymorphic selector equation 8.2: display the inserted index abstraction, instantiate it at the two opening record types, and display the emitted @1 and @2 applications before replaying both selections. Then place a second record-kinded type abstraction inside the selector body and verify that a projection from the outer type still uses its outer index variable. Repeat with both binders requiring 𝖭𝖺𝗆𝖾 and verify that the emitted names 𝐼𝑟,𝖭𝖺𝗆𝖾 and 𝐼𝑠,𝖭𝖺𝗆𝖾 are distinct. Finally, compile a record-kinded type application whose operator is a source variable, so the application case cannot inspect the operator for a syntactic type abstraction. Represent source and target terms by separate recursive ASTs. The target AST must contain binder-bearing index abstraction, index application, vector construction, and vector selection nodes. Pretty-print the structures computed by compilation rather than fixed trace literals, and keep compilation separate from evaluation so each success line is conditional on the emitted syntax and its result.