Functional objects and recursive object representations
appendix sectionrules
Functional objects and recursive object representations
For distinct labels, the source extension is 𝐴::=⋯∣[ℓ𝑖:𝐵𝑖]𝑖∈𝐼,𝑎::=⋯∣[ℓ𝑖=𝜍(𝑠𝑖:𝐴)𝑏𝑖]𝑖∈𝐼::=∣𝑎.ℓ∣𝑎.ℓ⇐𝜍(𝑠:𝐴)𝑏. Its three primitive typing rules are
𝐴=[ℓ𝑖:𝐵𝑖]𝑖∈𝐼Γ,𝑠𝑖:𝐴⊢𝑏𝑖:𝐵𝑖(𝑖∈𝐼)
Γ⊢[ℓ𝑖=𝜍(𝑠𝑖:𝐴)𝑏𝑖]𝑖∈𝐼:𝐴
T-Object
Γ⊢𝑎:[ℓ𝑖:𝐵𝑖]𝑖∈𝐼𝑗∈𝐼
Γ⊢𝑎.ℓ𝑗:𝐵𝑗
T-Invoke
Γ⊢𝑎:𝐴𝐴=[ℓ𝑖:𝐵𝑖]𝑖∈𝐼Γ,𝑠:𝐴⊢𝑏:𝐵𝑗𝑗∈𝐼
Γ⊢𝑎.ℓ𝑗⇐𝜍(𝑠:𝐴)𝑏:𝐴
T-Override
Objects are values, evaluation is weak. Put 𝑣=[ℓ𝑖=𝜍(𝑠𝑖:𝐴′)𝑏𝑖]𝑖∈𝐼. The roots are 𝑣.ℓ𝑗⟼𝑏𝑗[𝑣/𝑠𝑗],𝑣.ℓ𝑗⇐𝜍(𝑠:𝐴)𝑐⟼[ℓ𝑗=𝜍(𝑠:𝐴′)𝑐,ℓ𝑖=𝜍(𝑠𝑖:𝐴′)𝑏𝑖]𝑖≠𝑗. The second root records the runtime minimum type 𝐴′, where 𝐴′<:𝐴. Width-invariant subtyping and subsumption are
𝐴<:𝖳𝗈𝗉
S-Top
𝐽⊆𝐼𝐵𝑗=𝐶𝑗(𝑗∈𝐽)
[ℓ𝑖:𝐵𝑖]𝑖∈𝐼<:[ℓ𝑗:𝐶𝑗]𝑗∈𝐽
S-Object
Γ⊢𝑎:𝐴𝐴<:𝐵
Γ⊢𝑎:𝐵
T-Sub
Minimum typing removes T-Sub; variables, ground forms, and invocation remain syntax directed, while formation and override become
𝐴=[ℓ𝑖:𝐵𝑖]𝑖∈𝐼Γ,𝑠𝑖:𝐴⊢min𝑏𝑖:𝐵′𝑖𝐵′𝑖<:𝐵𝑖(𝑖∈𝐼)
Γ⊢min[ℓ𝑖=𝜍(𝑠𝑖:𝐴)𝑏𝑖]𝑖∈𝐼:𝐴
M-Object
𝐴=[ℓ𝑖:𝐵𝑖]𝑖∈𝐼Γ⊢min𝑎:𝐴′𝐴′<:𝐴Γ,𝑠:𝐴⊢min𝑏:𝐵′𝐵′<:𝐵𝑗𝑗∈𝐼
Γ⊢min𝑎.ℓ𝑗⇐𝜍(𝑠:𝐴)𝑏:𝐴
M-Override
Γ⊢min𝑎:[ℓ𝑖:𝐵𝑖]𝑖∈𝐼𝑗∈𝐼
Γ⊢min𝑎.ℓ𝑗:𝐵𝑗
M-Invoke
Fluent methods use the iso-recursive equation 𝖯𝗈𝗂𝗇𝗍=𝜇𝑋.[𝑥:𝖭𝖺𝗍,get:𝖭𝖺𝗍,move:𝑋] with the fold/unfold rules of subappendix A.21.
The translation target 𝐹<:𝜇 adds arrows, covariant records, bounded existentials, and iso-recursive types. Its characteristic subtyping calculus has formation rules
Δ⊢𝑆𝗍𝗒𝗉𝖾Δ⊢𝑇𝗍𝗒𝗉𝖾
Δ⊢𝑆→𝑇𝗍𝗒𝗉𝖾
FT-Arr
Δ⊢𝑆𝑖𝗍𝗒𝗉𝖾(𝑖∈𝐼)
Δ⊢{𝑘𝑖:𝑆𝑖}𝑖∈𝐼𝗍𝗒𝗉𝖾
FT-Record
Δ⊢𝑆𝗍𝗒𝗉𝖾Δ,𝑋<:𝑆⊢𝑇𝗍𝗒𝗉𝖾
Δ⊢∃𝑋<:𝑆.𝑇𝗍𝗒𝗉𝖾
FT-Exists
Δ,𝑋<:𝖳𝗈𝗉⊢𝑇𝗍𝗒𝗉𝖾
Δ⊢𝜇𝑋.𝑇𝗍𝗒𝗉𝖾
FT-Mu
Its structural subtyping rules are
Δ⊢𝑆𝗍𝗒𝗉𝖾
Δ⊢𝑆<:𝑆
S-Refl
Δ⊢𝑅<:𝑆Δ⊢𝑆<:𝑇
Δ⊢𝑅<:𝑇
S-Trans
𝑋<:𝑆∈Δ
Δ⊢𝑋<:𝑆
S-Bound
Δ⊢𝑆𝗍𝗒𝗉𝖾
Δ⊢𝑆<:𝖳𝗈𝗉
S-Top
Its characteristic subtyping rules are
𝑆′<:𝑆𝑇<:𝑇′
𝑆→𝑇<:𝑆′→𝑇′
S-Arr
𝐽⊆𝐼𝑆𝑗<:𝑇𝑗(𝑗∈𝐽)
{𝑘𝑖:𝑆𝑖}𝑖∈𝐼<:{𝑘𝑗:𝑇𝑗}𝑗∈𝐽
S-Rec
𝑆<:𝑆′𝑋<:𝑆⊢𝑇<:𝑇′
∃𝑋<:𝑆.𝑇<:∃𝑋<:𝑆′.𝑇′
S-Exists
𝑌<:𝖳𝗈𝗉,𝑋<:𝑌⊢𝑆<:𝑇
𝜇𝑋.𝑆<:𝜇𝑌.𝑇
S-Amber
Ordinary target typing is generated by
𝑥:𝑆∈Γ
Δ;Γ⊢𝑥:𝑆
F-Var
Δ;Γ⊢𝑡:𝑆Δ⊢𝑆<:𝑇
Δ;Γ⊢𝑡:𝑇
F-Sub
Δ;Γ,𝑥:𝑆⊢𝑡:𝑇
Δ;Γ⊢𝜆𝑥:𝑆.𝑡:𝑆→𝑇
F-Lam
Δ;Γ⊢𝑡:𝑆→𝑇Δ;Γ⊢𝑢:𝑆
Δ;Γ⊢𝑡𝑢:𝑇
F-App
Δ;Γ⊢𝑡𝑖:𝑆𝑖(𝑖∈𝐼)
Δ;Γ⊢{𝑘𝑖=𝑡𝑖}𝑖∈𝐼:{𝑘𝑖:𝑆𝑖}𝑖∈𝐼
F-Record
Δ;Γ⊢𝑡:{𝑘𝑖:𝑆𝑖}𝑖∈𝐼𝑗∈𝐼
Δ;Γ⊢𝑡.𝑘𝑗:𝑆𝑗
F-Proj
The exact boundary rules are
𝑅<:𝑆Δ;Γ⊢𝑡:𝑇[𝑅/𝑋]
Δ;Γ⊢𝗉𝖺𝖼𝗄𝑋<:𝑆=𝑅𝗐𝗂𝗍𝗁𝑡𝖺𝗌∃𝑋<:𝑆.𝑇:∃𝑋<:𝑆.𝑇
F-Pack
Δ;Γ⊢𝑝:∃𝑋<:𝑆.𝑇Δ,𝑋<:𝑆;Γ,𝑥:𝑇⊢𝑢:𝑈𝑋∉𝖥𝖵(𝑈)
Δ;Γ⊢(𝗈𝗉𝖾𝗇𝑝𝖺𝗌𝑋<:𝑆,𝑥:𝑇𝗂𝗇𝑢):𝑈
F-Open
Δ;Γ⊢𝑡:𝑇[𝜇𝑋.𝑇/𝑋]
Δ;Γ⊢𝖿𝗈𝗅𝖽𝜇𝑋.𝑇𝑡:𝜇𝑋.𝑇
F-Fold
Δ;Γ⊢𝑡:𝜇𝑋.𝑇
Δ;Γ⊢𝗎𝗇𝖿𝗈𝗅𝖽𝑡:𝑇[𝜇𝑋.𝑇/𝑋]
F-Unfold
If 𝐹=𝑆1→⋯→𝑆𝑛→𝑇, recursive creation is typed by
Δ;Γ,𝑓:𝐹,𝑥1:𝑆1,…,𝑥𝑛:𝑆𝑛⊢𝑡:𝑇Δ;Γ,𝑓:𝐹⊢𝑢:𝑈
Δ;Γ⊢𝗅𝖾𝗍𝗋𝖾𝖼𝑓(𝑥𝑖:𝑆𝑖)𝑛𝑖=1:𝑇=𝑡𝗂𝗇𝑢:𝑈
F-Letrec
Opening an actual package annotated ∃𝑌<:𝑆0.𝑇0 at a subsumed existential type contracts using its actual witness and payload: 𝗈𝗉𝖾𝗇(𝗉𝖺𝖼𝗄𝑌<:𝑆0=𝑅𝗐𝗂𝗍𝗁𝑡𝖺𝗌∃𝑌<:𝑆0.𝑇0)𝖺𝗌𝑋<:𝑆,𝑥:𝑇𝗂𝗇𝑢⟼𝑢[𝑅/𝑋][𝑡/𝑥]. For 𝐴=[ℓ𝑖:𝐵𝑖]𝑖∈𝐼, put 𝐴∗=𝜇𝑌.∃𝑋<:𝑌.𝐶𝐴(𝑋),𝐶𝐴(𝑋)={ℓ𝗌𝖾𝗅𝑖:𝑋→𝐵∗𝑖,𝗌𝖾𝗅𝖿:𝑋,ℓ𝗎𝗉𝖽𝑖:(𝑋→𝐵∗𝑖)→𝑋}𝑖∈𝐼. The recursive declaration is 𝐷𝐴≡create(𝑓𝑖:𝐴∗→𝐵∗𝑖)𝑖∈𝐼:𝐴∗=𝖿𝗈𝗅𝖽𝐴∗(𝗉𝖺𝖼𝗄𝑋<:𝐴∗=𝐴∗𝗐𝗂𝗍𝗁{ℓ𝗌𝖾𝗅𝑖=𝑓𝑖,ℓ𝗎𝗉𝖽𝑖=𝜆𝑔:𝐴∗→𝐵∗𝑖.create(¯𝑓[𝑖:=𝑔]),𝗌𝖾𝗅𝖿=create(¯𝑓)}𝖺𝗌∃𝑋<:𝐴∗.𝐶𝐴(𝑋)). With 𝑟𝐷𝐴=𝗅𝖾𝗍𝗋𝖾𝖼𝐷𝐴𝗂𝗇create, the exact object clause is trΓ([ℓ𝑖=𝜍(𝑠𝑖:𝐴)𝑏𝑖]𝑖∈𝐼)=𝑟𝐷𝐴(𝜆𝑠𝑖:𝐴∗.trΓ,𝑠𝑖:𝐴(𝑏𝑖))𝑖∈𝐼. Unfolding the recursive function places the literal same term 𝑟𝐷𝐴(¯𝑓) in its 𝗌𝖾𝗅𝖿 field and places 𝑟𝐷𝐴(¯𝑓[𝑖:=𝑔]) in update field 𝑖. Invocation unfolds, opens, selects ℓ𝗌𝖾𝗅𝑗, and supplies 𝗌𝖾𝗅𝖿; override selects ℓ𝗎𝗉𝖽𝑗 and supplies the translated replacement.