Abstract of thesis entitled“Iso-Type Systems: Simple Dependent Type Theories for Programming”
Submitted by
Yanpeng Yangfor the degree of Doctor of Philosophy
at The University of Hong Kongin January, 2019
Dependent types have been drawing a lot of attention in programming language designs. A key
reason is that they allow unifying types and terms that are usually distinct syntactic levels in
traditional language designs. Unified syntax brings some interesting advantages over separate
syntax, including added expressiveness and less duplication of concepts. However, it is challenging
to combine dependent types with common programming features, such as unrestricted generalrecursion and object-oriented programming (OOP) features including subtype polymorphism andabstract type members. To address these challenges, we propose three novel dependently typed
calculi with both simplicity and expressiveness, namely Pure Iso-Type Systems (PITS), the λI6
calculus and the λIΣ calculus.
PITS is a generic language framework that employs unified syntax, supports general recursion
and preserves decidable type checking. It is comparable in simplicity to pure type systems (PTS),
and is useful to serve as a foundation for functional languages that stand in-between traditional
ML-like languages and full-spectrum dependently typed languages. The key to retain decidable
type checking in the presence of general recursion is a generalization of iso-recursive types called
iso-types. Iso-types replace the implicit conversion rule typically used in dependently typed
calculi and make every computation explicit via cast operators. We study three variants of PITS
that differ on the reduction strategy employed by the cast operators and prove type-safety anddecidability of type checking for all variants.
The λI6 calculus is a variant of PITS with unified subtyping, a novel technique that unifies
typing and subtyping and enables the combination of dependent types and subtyping. In λI6 ,there is only one judgment that is akin to a typed version of subtyping. Both the typing relation, as
well as type well-formedness are just special cases of the unified subtyping relation. λI6 supports
essential features for modeling OOP, such as high-order subtyping, bounded quantification andtop types. It can fully subsume System F6 and enjoys several standard and desirable properties,
such as type-safety and transitivity of subtyping.
The λIΣ calculus is a variant of λI6 with strong dependent sums. Strong sums are useful tomodel Scala-like traits with type members. λIΣ adopts a novel treatment of strong sums called
iso-strong sums. The destructors of iso-strong sums are typed using intermediate type-levelapplications instead of standard direct substitutions. The necessary type-level computation canbe done by just call-by-value casts. λIΣ supports impredicativity and enjoys the same desirable
properties as λI6 , including type-safety and transitivity. (421 words)

Iso-Type Systems: Simple Dependent Type
Theories for Programming

Yanpeng Yang
楊彥芃Department of Computer Science
The University of Hong Kong

This dissertation is submitted in partial fulfillment of
the requirements for the degree ofDoctor of Philosophy
January, 2019

Declaration

I hereby declare that the thesis entitled “Iso-Type Systems: Simple Dependent Type Theories for
Programming” represents my own work and has not been previously submitted to this or any
other institution for a degree, diploma or other qualifications.

Yanpeng Yang
January, 2019Acknowledgements

My thanks first go to my supervisor, Bruno Oliveira, who has been a great research advisor
and mentor. Bruno is so energetic and positive on research. Every meeting with him is just apleasure. He is very good at guiding students with his great patience and strong expertise. I
really appreciate the time he spent on brainstorming new research ideas with me and offering
constructive suggestions to me. I am very grateful to all his help and support.
During my time as a PhD student HKU, I am very fortunate to meet so many nice colleagues
and friends. The Programming Languages Group is a great place to do research and share laughter.
I would like to thank everyone in the group: Haoyuan Zhang, Weixin Zhang, Yanlin Wang,
Zhiyuan Shi, Xuan Bi, Ningning Xie, Huang Li, Jinxu Zhao, Xuejing Huang, Tomas Tauber, JoãoAlpuim and other people, just to name a few. I would also like to thank visiting scholars to
our group, who patiently listened to my research work and gave me helpful feedback: Prof.
Tom Schrijvers, Dr. Marco Servetto, Dr. Vilhelm Sjöberg, Dr. Tomoyuki Aotani (we also met at
OOPSLA’17), Dr. Nicholas Ng and Dr. Shin-Cheng Mu (who is also my thesis examiner).
The Department of Computer Science at HKU is a warm place to stay. I would like to thankmany professors at the department: my second supervisor Dr. Reynold C. K. Cheng, former Heads
of Department Prof. Francis C. M. Lau and Prof. Wenping Wang, Dr. Heming Cui, Dr. Chuan
Wu, Dr. Zhiyi Huang and Dr. Hubert Chan. I would also like to thank staffs from the general
office and technical support who are kind and always ready to help: Priscilla Chung, Olive Hui,
Veronica Yim, Patrick Au and the current and former clean ladies (sorry I forgot your names) who
helped me clean my office every week.
HKU is a fantastic place with so many brilliant and kind people. I have met many new friends
here who are really kind and helpful. My special thanks go to Luwei Cheng and Dominic Hung
Chit-Ho for your encouragement that helped me get over my most difficult time at HKU. I would
like to thank Jiancheng Ye from EEE department for showing me around Hong Kong when I
was new here. I would like to thank Kan Wu for your professional skills as Soldier: 76 and Mei
for covering me. I would like to thank colleagues from the Systems Lab: Huanxin Lin, Hao Wu,
Mingzhe Zhang, Weizhi Liu, King Tin Lam and the visiting professor Dr. Dengke Zhang, for the
past time when we worked together. I would like to thank other friends I met at HKU and I reallyenjoy the happy time with you: Zhangquan Wu, Fangying Wang, Shirui Lu, Yong Xu, GongxianZeng, Lingjie Liu, Jiatao Gu, Kai Han, Wei Liu, Haofeng Li, Qihang Sun, Yongfei Wang, Yujie Cao,
Zhou Xu, Shuang Tong and many names I forgot to mention.
I would also like to thank my old friends, who did not forget me when I was deserted in
Hong Kong. I would like to thank my undergraduate roommates and friends, who are just like
brothers: Sheng’guo Ren, Fan Gao, Yuxuan Shui and Yuzui Ye. I would like to thank my highschool classmates who welcomed me when I first came to Hong Kong, who gathered with me at
Hong Kong and who still remembered me and contacted me when I was in Hong Kong: Jiayan

Jiang, Tianyi Yang, Yushang Tang, Yumeng Guo, Xiaoyu Chen, Feng Zhu, Yue Shen, Chen Hang,
Xiaozhuo Cheng, Yuxin Chen, Peilu Wang and so many others.
I would like to thank my parents and my family. You are always my powerful and securebacking.
Finally, I especially offer my grateful thanks to my girlfriend Huoru Zhang for your constantsupport throughout my PhD study. I could never have done this work without your love andencouragement.

Contents

1 Introduction
1.1 Type Features of Static Type Systems . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 The Design Space of Dependently Typed Languages . . . . . . . . . . . . . . . . .
1.3 Motivations and Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.1 Unified Syntax, General Recursion and Decidable Type Checking . . . .
1.3.2 Combining Dependent Types and Subtyping . . . . . . . . . . . . . . . .
1.3.3 Combining Dependent Types and Strong Sums . . . . . . . . . . . . . .
1.4 Our Proposals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.4.1 Pure Iso-Type Systems and Iso-Types . . . . . . . . . . . . . . . . . . . . .
1.4.2 The λI6 Calculus and Unified Subtyping . . . . . . . . . . . . . . . . . .
1.4.3 The λIΣ Calculus and Iso-Strong Sums . . . . . . . . . . . . . . . . . . .
1.5 Contributions and Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1
1
4
6
6
8
9
11
11
12
12
13

2 Background
2.1 Pure Type Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Basics of PTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.2 Examples of PTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.3 Metatheory of PTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Dependent Sums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.1 Weak Sums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.2 Strong Sums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2.3 Comparison of Weak and Strong Sums . . . . . . . . . . . . . . . . . . . .
2.3 Iso-Recursive Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.1 Iso-Recursive versus Equi-Recursive Types . . . . . . . . . . . . . . . . .
2.3.2 Iso-Recursive Types in Haskell . . . . . . . . . . . . . . . . . . . . . . .
2.4 Subtyping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4.1 Important Subtyping Rules . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4.2 Bounded Quantification . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5 Path-Dependent Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15
15
15
17
19
20
20
20
21
21
22
23
24
24
25
27

I

29

Pure Iso-Type Systems

3 Overview of Iso-Types
3.1 Motivation and Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 Implicit Type Conversion in Pure Type Systems . . . . . . . . . . . . . .

31
32
32

3.1.2 Newtypes: Explicit Type Conversion in Haskell . . . . . . . . . . . . . .
3.1.3 Iso-Types: Explicit Type Conversion in PITS . . . . . . . . . . . . . . . .
3.1.4 General Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Iso-Types by Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.1 Fun Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.2 Combining Algebraic Datatypes with Advanced Features . . . . . . . . .
3.2.3 Object Encodings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.4 Fun with Full Reduction . . . . . . . . . . . . . . . . . . . . . . . . . . .

32
33
35
35
36
37
39
40

4 Pure Iso-Type Systems
4.1 Call-by-name Pure Iso-Type Systems . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.1 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.2 Operational Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.3 Typing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.4 The Two Faces of Recursion . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.5 Metatheory of Call-by-name PITS . . . . . . . . . . . . . . . . . . . . . .
4.2 Call-by-value Pure Iso-Type Systems . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1 Value Restriction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.2 Reduction with Open Terms . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.3 Metatheory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Iso-Types with Full Casts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 Full Casts with Parallel Reduction . . . . . . . . . . . . . . . . . . . . . . .
4.3.2 Metatheory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.3 Completeness to Pure Type Systems . . . . . . . . . . . . . . . . . . . .
4.4 Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.1 Direct Dynamic Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.2 Direct Proofs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.3 No Mutually Dependent Judgments . . . . . . . . . . . . . . . . . . . . .
4.4.4 Implicit Proofs by Reduction . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.5 Full Type-Level Computation . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.6 Consistency of Reduction . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.7 Decidability in the Presence of Recursion . . . . . . . . . . . . . . . . .

43
44
44
45
45
47
48
50
50
52
52
54
54
57
60
61
61
62
63
63
64
65
65

II

67

3.2

Iso-Types with Subtyping

5 Unifying Typing and Subtyping
5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.1 Unified Syntax versus Stratified Syntax . . . . . . . . . . . . . . . . . . .
5.1.2 Challenges in Combining Subtyping with Dependent Types . . . . . . .
5.1.3 Our Solution: Unified Subtyping . . . . . . . . . . . . . . . . . . . . . . .
5.1.4 Iso-Types: Dependent Types without Strong Normalization . . . . . . .
5.1.5 Example: Object Encodings using λI6 . . . . . . . . . . . . . . . . . . .
5.2 The λI6 Calculus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2.1 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2.2 Operational Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

69
69
70
70
71
72
73
76
76
77

5.3

5.4

5.5

5.6

5.2.3 Static Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The Metatheory of Unified Subtyping . . . . . . . . . . . . . . . . . . . . . . . .
5.3.1 Basic Lemmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.2 Transitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.3 Basic Lemmas, Revisited . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.4 Type Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Algorithmic Version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4.1 Bidirectional Type Checking . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4.2 Soundness and Completeness . . . . . . . . . . . . . . . . . . . . . . . .
Subsumption of System F6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.5.1 Translating System F6 to λI6 . . . . . . . . . . . . . . . . . . . . . . . .
5.5.2 Subsumption of Typing and Subtyping . . . . . . . . . . . . . . . . . . .
Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

77
80
80
82
84
84
86
87
88
89
89
89
90

6 Iso-Types with Strong Dependent Sums93
6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
6.1.1 The Trouble with Impredicativity and Strong Sums . . . . . . . . . . . . . 94
6.1.2 Iso-Strong Sums: Typing Strong Sums with Iso-Types . . . . . . . . . . .
95
6.1.3 Example: Type Members and Traits . . . . . . . . . . . . . . . . . . . . . . 97
6.1.4 ML Module Systems and Strong Sums . . . . . . . . . . . . . . . . . . .
99
6.2 The λIΣ Calculus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.2.1 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
6.2.2 Dynamic Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
6.2.3 Static Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
6.3 Metatheory of λIΣ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.3.1 Basic Lemmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.3.2 Transitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
6.3.3 Type Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
6.4 The Sig Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
6.4.1 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
6.4.2 Static Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
6.4.3 Elaboration Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
6.4.4 Soundness of Translation . . . . . . . . . . . . . . . . . . . . . . . . . . 119
7 Related Work121
7.1 Dependently Typed Calculi without Subtyping . . . . . . . . . . . . . . . . . . . . 121
7.1.1 Core Calculus for Functional Languages . . . . . . . . . . . . . . . . . . . 121
7.1.2 Unified Syntax with Decidable Type-checking . . . . . . . . . . . . . . . . 121
7.1.3 Unified Syntax with General Recursion and Undecidable Type Checking 122
7.1.4 Casts for Managed Type-level Computation . . . . . . . . . . . . . . . . 122
7.1.5 Restricted Recursion with Termination Checking . . . . . . . . . . . . . 123
7.2 Calculi with Subtyping and Dependent Types . . . . . . . . . . . . . . . . . . . 123
7.2.1 Subtyping with Unified Syntax . . . . . . . . . . . . . . . . . . . . . . . 123
7.2.2 Stratified Syntax with High-Order Subtyping . . . . . . . . . . . . . . . . 124
7.2.3 Stratified Subtyping Systems with Dependent Types . . . . . . . . . . . . 124

7.3

7.2.4 Subtyping with Restricted Dependent Types . . . . . . . . . . . . . . . . 125
Strong Sum Types and ML Modules . . . . . . . . . . . . . . . . . . . . . . . . . 125
7.3.1 Dependently Typed Calculi with Strong Sigma-types . . . . . . . . . . . 125
7.3.2 Strong Sigma-types with Subtyping . . . . . . . . . . . . . . . . . . . . . 126
7.3.3 Core Languages for Scala . . . . . . . . . . . . . . . . . . . . . . . . . . 126
7.3.4 Encoding ML Modules by Dependent Types . . . . . . . . . . . . . . . . . 127
7.3.5 Encoding ML Modules by F-ing Modules . . . . . . . . . . . . . . . . . . . 127
7.3.6 First-class ML Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
7.3.7 Module Systems for Dependently Typed Calculi . . . . . . . . . . . . . . 128

8 Conclusion and Future Work129
8.1 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
A Manual Proofs
135
A.1 Encoding Weak Sums in λI6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
A.2 Subsumption of System F6 in λI6 . . . . . . . . . . . . . . . . . . . . . . . . . . 136
A.3 Soundness of Translation for Sig . . . . . . . . . . . . . . . . . . . . . . . . . . 140
References

151

List of Figures

2.1
2.2
2.3

Typing rules of PTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
The lambda cube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
Specification of System F6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26

4.1 Syntax of call-by-name PITS . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Operational semantics of call-by-name PITS . . . . . . . . . . . . . . . . . . . .
4.3 Typing rules of call-by-name PITS . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4 Call-by-value PITS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5 One-step decidable parallel reduction of erased terms . . . . . . . . . . . . . . .
4.6 Erasure of casts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7 PTSµ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8 Full PITS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9 Full beta reduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.10 Typing rules of PTSstep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

45
46
46
53
55
55
56
57
58
60

5.1
5.2
5.3
5.4
5.5
5.6
5.7
5.8
5.9

Evaluation of (c ⇐ bump) ⇐ get . . . . . . . . . . . . . . . . . . . . . . . . . .
Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Operational semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Static semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dependency of lemmas for the metatheory of unified subtyping . . . . . . . . . .
Erasure of annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Algorithmic subtyping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Bidirectional typing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Translation of System F6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

75
77
78
79
81
87
87
88
89

6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9

Syntax of λIΣ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Operational semantics of λIΣ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Static semantics of λIΣ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Syntax of Sig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Typing rules of Sig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Other rules of Sig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Translation of terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Translation of terms (cont.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Translation of contexts and bindings . . . . . . . . . . . . . . . . . . . . . . . . 119

List of Tables

4.1

Comparison between PTSf and PITS . . . . . . . . . . . . . . . . . . . . . . . .

6.1

Properties of dependently typed calculi with beta equality . . . . . . . . . . . . . 94

7.1

Comparison between λI6 and related calculi . . . . . . . . . . . . . . . . . . . .

62

123

1

CHAPTER

1

Introduction

1.1

Type Features of Static Type Systems

Type systems describe how types are assigned for terms in programming languages. Static typechecking employs rules of type systems to verify types at compile-time. Static type systems help
detect errors early before the program actually runs. For example, if the operator “/” performs
integer division and one accidentally writes a division by two on the string, i.e. "3"/2, thecompiler will detect a type mismatch that the operand "3" is not an integer. Such ill-typed term
will be rejected by the compiler and prevented from crashing at run-time. From the perspectiveof engineering, static type systems can be beneficial for code refactoring and optimization by
utilizing the extra typing information about programs. There is even a trend of adding static typesystems to dynamically typed languages. For example, Python allows type annotations startingfrom Python 3.5 [van Rossum et al. 2014] and TypeScript [Microsoft Corporation 2016] brings anoptional type system to JavaScript through gradual typing [Siek and Taha 2006].
Subtyping. Statically typed languages support various type features through their type systems.
For example, object-oriented programming (OOP) languages, such as Java [Gosling et al. 1996]
and Scala [Odersky et al. 2004], usually support subtype polymorphism of objects, which is a key
feature of OOP. Such mechanism relies on the subtyping relation of type systems. In Scala, we
can define classes that implement the same method but behave differently:
trait Shape {def area(): Double}class Square extends Shape {var width = 1.0
def area() = width * width}class Circle extends Shape {var radius = 1.0
def area() = Math.PI * radius * radius}

Both Square and Circle classes are subtypes of Shape, meaning that we can pass Square orChapter 1. Introduction

2

Circle objects to the places expecting Shape objects. For example, we can define a genericfunction PrintArea that prints the area of a Shape object. We can pass a Square or Circle object
to PrintArea and get different results:
def PrintArea(s: Shape) = println(s.area())
PrintArea(new Square())// 1.0PrintArea(new Circle())// 3.141592653589793

Higher-kinded Polymorphism. In contrast to the subtype polymorphism in OOP languages,
type systems of functional programming languages, such as Haskell [Marlow et al. 2010] andML [Milner et al. 1990], usually adopt other forms of polymorphism. For example, Haskell supports
higher-kinded polymorphism, which is achieved by higher-kinded types that can take other types
and construct a new type. One example are monads, a useful design pattern that can represent
sequential computations [Wadler 1995]. Monads in Haskell are defined by a typeclass [Hall et al.
1994] (like an interface in Java) with two functions, bind (>>=) and return:class Monad m where(>>=) :: m a → (a → m b) → m b
return :: a → m a
Monad is an example of a higher-kinded type, which has the following kind:
Monad :: (? → ?) → Constraint
It takes a type constructor m of kind ? → ? and returns a typeclass constraint. This enables
abstraction over not only types but also type constructors, thus obtaining higher-kinded polymorphism. For example, many type constructors in Haskell can be categorized into monads andoperated using the bind or return functions, such as list types and Maybe types (also known as
option types). With higher-kinded polymorphism, it is possible to write a generic fmap functionthat performs operations for each element inside a monad:
fmap :: Monad m ⇒ (a → b) → m a → m b
fmap f x = x >>= λy → return (f y)
The type constructor m can be a list or option type, which are both monads. For example, we canapply fmap (+1) to a list or option to increase contained elements by one:
fmap (+1) [1, 2, 3] -- returns [2, 3, 4]
fmap (+1) (Just 2) -- returns (Just 3)

Dependent Types. Besides traditional OOP and functional languages, several new programming languages, notably Agda [Norell 2007a] and Idris [Brady 2013], are emerging and employ adifferent programming paradigm called dependently typed programming. Type systems in theselanguages support dependent types: types that can depend on terms. For example in Idris, we candefine a vector, a special list whose type carries its length:
data Vec : Nat → Type where
Nil : Vec 0(::) : Int → Vec n → Vec (1 + n)

1.1. Type Features of Static Type Systems

3

The vector type Vec is a dependent type that depends on a natural number Nat, i.e., the lengthof the list. Dependent types involve type-level computation, i.e., evaluating terms in types. For
example, consider an append function that concatenates two vectors:
append : Vec n → Vec m → Vec (n + m)
append Nil
ys = ysappend (x :: xs) ys = x :: append xs ys
The return type contains an addition expression n + m which needs evaluation to get its value.
For example, if we append h1, 2i of type Vec 2 with h3i of type Vec 1, the resulting list h1, 2, 3i
will have type Vec (2 + 1). We need to further perform the computation 2 + 1 = 3 to eliminate
the addition form and obtain the final type Vec 3. In contrast, traditional languages rarely involve
computations at the type level and usually have a strong distinction between terms and types.
Benefits of Dependent Types. Dependent types have been drawing a lot of attention inprogramming language design and research in recent years [Augustsson 1998; Altenkirch et al.
2010; Sjöberg et al. 2012; Stump et al. 2008; Weirich et al. 2013; Gundry 2013; Casinghino et al. 2014;
Sjöberg and Weirich 2015; Sjöberg 2015; Eisenberg 2016; Casinghino 2014; Weirich et al. 2017].
A key reason why dependent types are interesting is that they naturally lead to a unification
between types and terms, which enables both additional expressiveness and economy of concepts.
Dependent type systems are more expressive because types can carry more information aboutterms. For example, by using vector types Vec, we can statically know the length of lists. In
contrast, if using conventional list types, such as List<T> in Java, we can only know their lengths
at run-time through the size() method. Thus, the dependent list type provides more refined type
information (the exact list length) and is helpful to prevent more errors earlier at compile-time,such as out-of-bounds errors.
The other potential benefit of dependent types comes from the fact that as terms are allowed
to occur in types, the strong separation between terms and types is no longer necessary. Oncevarious different levels of syntax (such as terms and types) are unified, the redundancy of language
constructs at the various levels can be avoided. For example, Java uses a special syntax for
instantiating generics, e.g., List<Object>, which is different from an ordinary method call suchas Arrays.sort(a). The type operator List is essentially a type-level function and its instantiation
can be seen as a function application. Supposing that we unify term and type levels in Java, we
can instantiate generics just like calling methods, e.g., List(Object). This leads to an economy ofconcepts: with unified syntax, there can be just one form of functions for both type-level functions(generics) and term-level functions (methods). Moreover, traditional functional languages like
Haskell [Marlow et al. 2010] and ML [Milner et al. 1990] that support higher-kinded types haveeven more levels in the stratified syntax, i.e., terms, types and kinds. Unifying syntactic levels
in such languages can result in a significantly more compact metatheory, and can also lead to a
reduction of necessary implementation effort.
Benefits of Combining Type Features. Modern programming languages tend to support
multiple type features simultaneously. Combining type features enables the possibility of writing
programs in different programming paradigms. For example, Scala supports both subtyping andhigher-kinded types. Not only can we write Scala programs in the object-oriented style, but also
in the functional style, e.g., defining a Monad trait in Scala as follows:Chapter 1. Introduction

4
trait Monad[M[_]] {def ret[A](a: A): M[A]def bind[A, B](m: M[A], f: A => M[B]): M[B]}The Monad trait follows the Monad typeclass definition in Haskell and can also quantify overtype constructors, such as the Option[T] type in Scala.
Moreover, with different type features combined, the language becomes more expressive andenables more programming features. For example, combing subtyping and higher kinds enables
higher-order subtyping in Scala, which allows subtyping relations between type constructors. We
can define a non-empty list type Cons[T], which is a subtype of the general linked list type L[T]:trait L[T] {def isEmpty: Boolean
def head: T
def tail: L[T]}class Cons[T](val head: T, val tail: L[T]) extends L[T] {def isEmpty = false}

1.2

The Design Space of Dependently Typed Languages

Conventionally, dependent types are used as a logic to implement programming languages aiming
at theorem proving, e.g., Twelf [Pfenning and Schürmann 1999] and Coq [The Coq development
team 2016]. This is made possible by the Curry-Howard correspondence [Howard 1980] whichconnects the world of logics and the world of programming languages. The correspondence statesthat propositions in logic can be viewed as types and proofs can be viewed as program values. The
expressiveness of dependent types makes languages like Twelf and Coq suitable as proof assistants.
With dependent types, types can mention terms and correspondingly we can illustrate usefulpropositions containing terms. For example in Coq, we can write equality propositions to describe
properties of additions such as a + b = b + a for commutativity and (a + b) + c = a + (b + c)
for associativity.
To serve as proof assistants, languages like Twelf and Coq are also required to be consistent
when viewed as logics. Logical consistency is critical to proof assistants, which guarantees that
proofs will not go wrong, e.g., one can never derive a term of type False or prove an absurd
result True = False. Logical consistency is often ensured by strong normalization, a property
that evaluating well-formed terms or types always terminates.
Apart from the common logical use, dependent types can also be beneficial to the area of
traditional general-purpose programming. Dependently typed languages like Coq, Agda and Idris
are designed to be both proof assistants and programming languages. However, the combination of
dependent types and traditional programming features may cause problems. Traditional languages
allow users to write recursive programs without restrictions. This is not the case in languages like
Coq, Agda and Idris.
Otherwise, non-terminating recursive programs would break crucial properties of proofs
assistants, such as strong normalization, logical consistency or decidable type checking, i.e. the type

1.2. The Design Space of Dependently Typed Languages

5checking algorithm always terminates. At the type level, non-terminating recursive functions
can show up in definitions of dependent types. Strong normalization no longer holds sinceevaluation of such types may not terminate. Type checking may also involve the evaluation of
non-terminating types and becomes undecidable. At the term level, non-terminating programs
can be used to prove arbitrary theorems. For example, we can build a fixpoint combinator fix
using a recursive definition:
fix : (A → A) → A
fix f = f (fix f )With fix , we can prove an absurd theorem True = False, i.e., find a term with such type:
fix id : (True = False)
where id = λx : (True = False). x
This leads to logical inconsistency since we can prove a wrong result True = False.
Termination and Positivity Checking. Generally determining whether a recursive function
terminates or not is essentially the halting problem, which is undecidable [Turing 1937]. Dependently typed languages usually take a conservative approach by limiting how recursive programsand types can be written, enforced by various checks including termination checking and positivity
checking.
Termination checking requires recursive functions to have specific forms that are known toterminate. For example, Coq employs a restriction called primitive recursion [Bertot and Castran2010; Chlipala 2013], which only allows recursive calls on syntactic sub-terms of the original
arguments. Terminating total functions that are not primitive recursive cannot be directly written
in Coq, e.g., the Ackermann function [Ackermann 1928; Bertot and Castran 2010]:
Ack (0, n)= n+1
Ack (m + 1, 0)= Ack (m, 1)
Ack (m + 1, n + 1) = Ack (m, Ack (m + 1, n))Positivity checking forbids recursive datatypes that occur in negative positions since suchdatatypes allow users to write non-terminating functions. The following datatype definition is a
simple example that violates the positivity checking of Coq [Bertot and Castran 2010]:
Inductive T : Set := MkT : (T -> T) -> T.

but can be defined in Haskell without any issue:
data T = MkT (T → T )Issues of Termination and Positivity Checking. The termination and positivity checkers
make these dependently typed languages non-starters for traditional programming styles basedon general recursion. Programmers need to struggle with these checkers to let programs compile.
Termination checkers are usually not intelligent enough to detect terminating programs, such as
the Ack function. Another example is the implementation of merge sort in Coq. The following
definition intuitively implements the algorithm of merge sort, which is terminating, but cannot
pass the termination checker [Chlipala 2013]:

Chapter 1. Introduction

6

Fixpoint mergeSort (xs : list A) : list A :=if leb (length xs) 1
then xs
else let xss := split xs inmerge (mergeSort (fst xss)) (mergeSort (snd xss)).

In contrast, Haskell programmers can write a recursive merge sort function more freely without
any restriction:
mergeSort [ ] = [ ]mergeSort [x ] = [x ]mergeSort xs = let (a, b) = split xs
in merge (mergeSort a) (mergeSort b)
Our Focus. The design space between traditional languages and full-spectrum dependently
typed languages is very large. It would be interesting if there are language designs that employ
dependent types and benefit from the added expressiveness and economy of concepts, but also
enjoy the liberty of writing recursive functions and types without termination or positivity
checking. Previously, researchers have explored such languages designs and proposed dependently
typed calculi with general recursion, such as Cayenne [Augustsson 1998] and Zombie [Casinghino
et al. 2014; Sjöberg and Weirich 2015]. They showed the feasibility of combining dependent types
with general recursion for general-purpose programming.
This thesis mainly focuses on such design space. We explore designs of languages that
employ dependent types, but aim at traditional programming instead of theorem proving. In suchlanguages, general recursive programs and types can be freely written. Decidable type checking
is a desirable property, while strong normalization or logical consistency are not guaranteed. The
termination/positivity checking can be avoided, which makes these languages less restrictive interms of writing recursive programs and thus more friendly to end users. However, dependent
types do not come for free and several challenges may arise when combining dependent types
with other programming features, as discussed later in the next section.

1.3

Motivations and Challenges

Our goal of this thesis is to explore how to combine dependent types with traditional programming
features in simple yet expressive calculi that are friendly to formalization, implementation andextension. In this section, we discuss the motivations and challenges of combining dependent
types with various features, including general recursion, subtyping and strong dependent sums.

1.3.1

Unified Syntax, General Recursion and Decidable Type Checking

Dependent types enable unifying types and terms. By employing unified syntax with dependent
types, it is possible to design a calculus that is both simple and expressive. One existing example
is the Pure Type Systems (PTS) [Barendregt 1991, 1992] that have only one syntactic level for bothterms and types. PTS has a very concise presentation consisting of only 5 language constructs
and 7 typing rules. It is also powerful to subsume a wide range of typed lambda calculi, including
the calculus of constructions [Coquand and Huet 1988] containing dependent types.
Though PTS does not contain any explicit forms of recursion and is typically used as aframework to study logic systems, the approach of PTS-style unified syntax can be helpful

1.3. Motivations and Challenges

7

for traditional language designs. Unifying different syntactic levels removes the duplicationof constructs and reduces the effort of formalization and implementation. Not surprisingly,
researchers have in the past proposed several dependently typed languages with unified syntax
and general recursion. These languages can both model the traditional programs with recursion
and allow using dependent types to write expressive and type-safe programs that cannot usually
be done in traditional languages. For example, Cayenne [Augustsson 1998] is a Haskell-like
dependently typed language with unified syntax. Cayenne allows users to write a type-safe format
printing function, i.e., printf, which has the following type:
printf :: (fmt :: String) -> PrintfType fmt

The type of printf is a dependent type whose return type is determined by the fmt string. A
type-level function PrintfType recursively computes the type of printf according to the provided
fmt. Thanks to the unified syntax, it is defined just like any other recursive functions:
PrintfType :: String -> *PrintfType ""= String
PrintfType (’%’:’d’:cs) = Int ->PrintfType cs
PrintfType (’%’:’s’:cs) = String -> PrintfType cs
PrintfType (’%’: _ :cs) =PrintfType cs
PrintfType ( _ : cs
) =PrintfType cs
PrintfType ensures that printf only accepts arguments with correct types specified by theformat string. For example, when fmt is "%d", we haveprintf "%d" :: Int -> String

which only accepts an integer and prevents malformed inputs. Note that the type-safe printf
example only requires a few, finite steps of type-level computation. It can actually be simulated in
Haskell with other existing type-level features such as typeclasses or Template Haskell [Sheard
and Jones 2002]. Nonetheless, the simulation is not as convenient or intuitive as programming in
Cayenne directly using dependent types.
Challenges. However, in dependently typed calculi with unified syntax, it is non-trivial tosimultaneously integrate general (unrestricted) recursion and retain decidable type checking. For
example, type checking of Cayenne is undecidable. The reason is that as dependent types involve
type-level computation, the type checker may get stuck if trying to evaluate non-terminating
terms that show up in types. For example, recall the fixpoint combinator in Section 1.2. If there
exists a vector type with fix as follows:
Vec (fix (λx : Nat. x + 1))
The type checker will get stuck when evaluating the parameter of Vec, which is a non-terminating
operation that infinitely adds one to the result. Moreover, unified syntax removes the syntactic
boundary between terms and types, allowing us to use the same fix combinator to directly
construct a recursive type:
fix id : ?
where id = λx : ?. x
The type fix id can be unfolded indefinitely, which may also block the type checker. For languages
with stratified syntax, we can still make syntactic restrictions to prevent recursive terms (e.g. fix )Chapter 1. Introduction

8

being directly used as types. But this is usually difficult for languages with unified syntax whoseterms can be freely lifted to the type level as types.
Besides Cayenne, there are several other dependently typed calculi supporting unified syntax
and general recursion, such as the calculus by Cardelli [1986b] and the ΠΣ calculus by Altenkirch
et al. [2010]. But both calculi fail to retain decidable type checking similarly to Cayenne. For
pragmatic reasons, some theorem provers with unified syntax, e.g., Idris and Agda, provide an
option to turn off the termination checker and allow general recursion, but the type checking
becomes undecidable. More recently, several studies have proposed dependently typed calculi
with unified syntax and also managed to preserve decidable type checking in the presence ofgeneral recursion. Notable examples are the Zombie language from the Trellys Project [Sjöberg
et al. 2012; Casinghino et al. 2014; Sjöberg and Weirich 2015; Casinghino 2014; Sjöberg 2015] andSystem DC from Dependent Haskell [Weirich et al. 2017]. However, these studies have more
ambitious goals and require more sophisticated mechanisms, such as logical subsystems and typeequality. The resulting calculi are significantly more complex when compared to systems basedon PTS.

1.3.2

Combining Dependent Types and Subtyping

Besides functional programming in Haskell and ML, object-oriented programming (OOP) is a
popular programming paradigm with “objects” at the core to encapsulate both data and programs.
Beyond the concept of objects, type systems for modern OOP languages are becoming more andmore complex. For example, Java was initially designed to be a relatively simple OOP languagethat tried to address many issues of C++ caused by its complexity. The core features of (original)Java can be formalized in a simple calculus called Featherweight Java (FJ) [Igarashi et al. 1999].
The syntax of classes in FJ is simple:
L ::= class C extends C {C f ; K M }With the growth of the language, many new features were introduced into modern Java. One
notable feature is parametric polymorphism, also known as generics, which is introduced in Java
5. To model generics, the original FJ is extended to Featherweight GJ (FGJ) [Bracha et al. 1998].
The syntax of classes in FGJ becomes more complex (/ is the abbreviation of extends):
L ::= class ChX / N i / N {T f ; K M }Moreover, Java continues evolving with more features, such as lambda expressions in Java 8 andlocal type inference in Java 10 [Goetz 2016], thus requires further extensions of core calculi toformalize these features. Another example is Scala, which supports even more advanced features
such as higher-order polymorphism [Girard 1972; Moors et al. 2008], type members [Odersky et al.
2003] and path-dependent types [Odersky et al. 2004; Rompf and Amin 2016]. The extra complexityof the type systems is reflected by the significant effort to develop the corresponding formal
theory. A notorious example of this is the development of the foundational metatheory for Scala,which has been an ongoing effort that lasted for more than 10 years and recently culminated with
the Dependent Object Types (DOT) calculus [Amin et al. 2012a].
Like functional languages, OOP languages can also benefit from dependent types for both
added expressiveness and economy of concepts. Given that the complexity of type systems for1.3. Motivations and Challenges

9

OOP languages is so high, techniques for bringing down such complexity, while retaining or evenincreasing expressiveness are certainly welcome. The economy of concepts afforded by unified
syntax typical of dependently typed languages can help here, since it can significantly reduce
the number of language constructs and relations needed in a calculus. Unfortunately, there has
been less work on dependently typed calculi for OOP. There are mainly two challenges whendeveloping such calculi. One challenge we already mentioned is the interaction between generalrecursion and dependent types. This applies to programming languages in general, and is not
limited to OOP languages.
The other challenge arises from the combination of subtyping and dependent types. OOP
supports polymorphism based on the subtyping relation. However, subtyping is also a substantial
difference to traditional calculi based on PTS which typically do not support such feature. The
issue with subtyping is well summarized by Aspinall and Compagnoni [1996]:
One thing that makes the study of these systems difficult is that with dependent types,
the typing and subtyping relations become intimately tangled, which meansthat tested techniques of examining subtyping in isolation no longer apply.
In essence the big difficulty is that the introduction of dependent types makes typing and subtyping
depend on each other. This causes several difficulties in developing the metatheory for calculi
that combine dependent types and subtyping. The metatheory becomes quite complex in some
calculi [Aspinall and Compagnoni 1996; Castagna and Chen 2001], e.g., the transitivity of subtyping
is entangled with strong normalization. Most previous attempts [Aspinall and Compagnoni 1996;
Zwanenburg 1999; Castagna and Chen 2001; Chen 1997, 2003] try to address the problem byuntangling typing and subtyping, so that the metatheory of subtyping can be developed before themetatheory of typing. One interesting exception is the Pure Subtype Systems (PSS) by Hutchins[2010] which completely eliminate types and only contain the subtyping relation. An unfortunate
result of these attempts is that several desirable language features can no longer be supported. For
example, several systems [Aspinall and Compagnoni 1996; Zwanenburg 1999] drop the support of
top types, which are essential in OOP programs to model the universal base class, e.g. the Object
type in Java. PSS does not support contravariance when subtyping functions, and its metatheory
is complex and not fully developed yet. No previous calculi have managed to subsume System
F6 [Cardelli et al. 1994] which is a canonical calculus capturing the essential OOP features.

1.3.3

Combining Dependent Types and Strong Sums

OOP languages like Scala and Rust [The Rust Project Developers 2011] support traits [Schärli et al.
2003] which are types that contain a set of methods. Scala and Rust also allow type members (alsocalled associated types) in traits, which are abstract types and useful to define generic datatypes
in a more modular way. For example, we can define an abstract trait of integer sets using typemembers in Scala:trait Set {type Tdef empty(): T
def member(x: Int, s: T): Boolean
def insert(x: Int, s: T): T}

Chapter 1. Introduction

10

The type member T represents the abstract type of a set implementation and can be mentioned bymethods. Alternatively, traits with type members can be formulated as traits with type parameters(i.e. generics):
trait Set[T] {def empty(): T
def member(x: Int, s: T): Boolean
def insert(x: Int, s: T): T}

However, abstract types (i.e. T) need to be exposed out of traits with generics. When referring
to Set[T], one needs to provide an actual T in advance to obtain a complete type. In contrast, if
formulated as type members, abstract types can be hidden inside traits. Thus, traits carrying with
type members can have higher cohesion thus better modularity.
To access abstract type members, one needs certain forms of dependent types. In Scala, this isdone by a weaker form of dependency, called path dependency [Amin et al. 2012a], which only
allows types to depend on “paths”, i.e., a chain of member access. For example, consider a genericfunction for testing if an element is in an abstract set:
def isMember (s: Set)(x: Int, t: s.T) = s.member(x, t)

The last parameter has the type s.T, which depends on a term, the first parameter s. The type s.T
is called a path-dependent type [Amin et al. 2014]. DOT utilizes path dependent types to model theaccess of abstract type members. However, DOT contains many features, such as a rich notion oftype bounds, aiming at modeling more features of Scala than only type members. It has a complex
metatheory that requires several new proof techniques [Rompf and Amin 2016; Rapoport et al.
2017].
If we only focus on encoding type members, we can alternatively use strong dependent sums
(or simply strong sums) in traditional dependently typed calculi. Dependent sums are generalized
pairs whose second component can depend on the first. For example, we can encode the Set trait
using a dependent sum type (i.e. Σ-type) with a record type:
Set = ΣT : ?. {empty : T ,member : Int → T → Bool ,insert : Int → T → T}
Strong sums allow us to use projections to access the components. Given a term s : Set, thesecond projection s.2 extracts the record and (s.2).member further extracts the function fromthe record. Moreover, strong sums can be used to model some other modular structures, such as
module systems of ML languages [MacQueen 1986; Milner et al. 1990].
However, combining strong sums in dependently typed calculi is also non-trivial. In traditional
dependently typed calculi that are impredicative, such as the calculus of constructions [Coquandand Huet 1988], the introduction of strong sums leads to logical inconsistency [Coquand 1986;
Hook and Howe 1986] and hence the loss of strong normalization. This makes it hard to preserve
desirable properties, especially in dependently typed calculi with subtyping (e.g. λP6 by Aspinall
and Compagnoni [1996]), whose properties such as transitivity and subject reduction rely on strong
normalization. Previous studies try to address this issue by dropping [Harper and Mitchell 1993]

1.4. Our Proposals

11

or partially dropping [Stump 2017; Bowman et al. 2017] the impredicativity, but the expressivenessof these calculi is also reduced.

1.4

Our Proposals

To address the challenges posed by combining dependent types with traditional programming
features, we propose three novel calculi, namely Pure Iso-Type Systems, the λI6 calculus and theλIΣ calculus. In these calculi, we manage to combine dependent types with features such as
general recursion, subtyping and strong sums by proposing several novel techniques, including
iso-types, unified subtyping and iso-strong sums. We mainly focus on traditional programming
scenarios that require few type-level computations, which fit well with our treatment of dependent
types. The proposed calculi enjoy both expressiveness and simplicity. By employing the unified
syntax of dependent types, the calculi are more concise and expressive than traditional nondependent calculi. Several advanced features of traditional languages, such as higher-kinded
polymorphism and higher-order subtyping, can be supported with minimal effort. The calculi arealso simple enough to enable the full development of formal metatheory and the possibility ofextensions. In the rest of this section, we briefly introduce our proposed calculi and techniques.

1.4.1

Pure Iso-Type Systems and Iso-Types

Pure Iso-Type Systems (PITS) are a family of calculi that employ unified syntax, support generalrecursion and preserve decidable type checking. PITS has a comparable level of simplicity to PTS,
consisting of only 8 language constructs and no more than 9 typing rules. The key to retaining
decidable type checking in the presence of general recursion is iso-types, a generalization of
iso-recursive types [Crary et al. 1999; Pierce 2002]. Iso-types view not only folding and unfoldingof recursive types but also any types that are (beta) convertible as isomorphic. Unlike PTS, there is
no implicit type-level computation in PITS. Each type-level computation step is explicitly triggeredby a term-level type-safe cast operator. Single-step computation is trivially terminating — it stops
after one step, thus type checking is decidable even with non-terminating programs at the typelevel. Meanwhile, term-level programs using general recursion can be non-terminating as intraditional languages. There is no termination checking or positivity checking in PITS.
We emphasize that PITS does sacrifice some convenience when performing type-level computations in order to gain the ability of doing arbitrary general recursion at the term level. The goalof proposing PITS is to show the use of PTS-style unified syntax for benefiting language designs
intended for traditional programming that only involves lightweight type-level computations, but
not intended for full-spectrum dependently typed programming that requires intensive type-levelcomputations. The design of PITS is suitable to serve as a foundation for languages in-between
traditional ones (e.g. ML and Haskell) and full-spectrum dependently typed ones (e.g. Idris andAgda). To illustrate the feasibility of using PITS as such a foundation, we build a simple surface
language called Fun. We show several advanced language features such as higher-kinded types
can be encoded in PITS by examples written in Fun.
PITS also enjoys the flexibility of choosing different reduction relations for the explicit castoperators. We study three variants of PITS, namely the call-by-name PITS, the call-by-value PITS
and the full PITS, which differ on the reduction strategy used by casts. The call-by-name/value
PITS uses conventional call-by-name/value reduction rules for casts. This leads to a relatively

Chapter 1. Introduction

12

simple metatheory that has direct proofs of properties. In contrast, the full PITS uses the more
expressive parallel reduction for casts, which can perform full beta-reduction. But the cost is thecomplex metatheory of full PITS that requires indirect proofs from an auxiliary system erasing
all casts. For all variants, we prove important results of metatheory, including type-safety anddecidability of type checking.

1.4.2

The λI6 Calculus and Unified Subtyping

The λI6 calculus is a dependently typed calculus with subtyping. To address the issues arisingfrom the combination of dependent types and subtyping, λI6 employs a novel technique called
unified subtyping, which unifies both typing and subtyping relations. The unified subtyping
relation can be viewed as a typed version of the conventional subtyping relation.
In λI6 , there is only one single form of judgment, i.e., the unified subtyping judgment. Thereis no separated typing or type well-formedness judgment, both of which are syntactic sugar of
the unified subtyping judgment. The issue of mutual dependency between typing and subtyping,which is a major problem in other formalizations [Aspinall and Compagnoni 1996; Castagna andChen 2001; Zwanenburg 1999] of calculi with dependent types and subtyping, does not exists in
λI6 , because the typing relation is essentially the (unified) subtyping relation itself. In contrast
to previous work that struggles with untangling typing and subtyping, we propose a different
approach that embraces such entanglement. Our approach is also fundamentally different from
Hutchins’ PSS since λI6 still retains types.
Meanwhile, λI6 is a dependently typed calculus and can be viewed as a variant of PITS. It
features the PTS-style unified syntax and employs the iso-type approach to address the issues ofcombining recursion and dependent types. Moreover, λI6 supports extra OOP features over PITS,
including higher-order subtyping [Pierce and Steffen 1997], bounded quantification [Cardelli et al.
1994] and top types. It can fully subsume System F6 and enjoys several standard and desirable
properties, such as type-safety and transitivity of subtyping.

1.4.3

The λIΣ Calculus and Iso-Strong Sums

The λIΣ calculus is a dependently typed calculus with strong sums. It is a variant of λI6 andalso based on the ideas of unified subtyping and iso-types. To address the challenges posed by
combining dependent types and strong sums, we propose iso-strong sums whose strong destructors(e.g. the second projection) are typed using iso-types. In λIΣ , cast operators employ the call-byvalue reduction, similarly to the one of call-by-value PITS. The typing results of the strong sum
destructors are intermediate type-level applications instead of standard direct substitutions. With
such change, all type-level computation for strong sums can be performed by just call-by-value
casts. There is no need of using full casts from the full PITS, which bring extra complexity in themetatheory.
At the same time, iso-types and iso-strong sums in λI6 decouple properties from strong
normalization. This makes it possible to support impredicative polymorphism in the presenceof iso-strong sums and retain desirable properties. λIΣ enjoys the same desirable properties as
λI6 , including type-safety and transitivity, both of which can be proved without requiring strong
normalization. For demonstration purposes, we also build a lightweight surface language Sig on
top of λIΣ . We show how Scala-like type members and traits can be encoded by strong sums ofλIΣ via a type-sound elaboration semantics of Sig.

1.5. Contributions and Outline

1.5

13

Contributions and Outline

Contributions. In summary, the main contributions of this thesis are:• Pure Iso-Type Systems: A variant of PTS with general recursion, unified syntax anddecidable type-checking. We prove type-safety and decidability of type checking for all
three variants of PITS.
• Iso-Types: A generalization of iso-recursive types, which makes all type-level computation
steps explicit via cast operators. The combination of casts and recursion subsumes isorecursive types.
• Reduction Strategies of PITS: We study PITS with three reduction strategies: call-byname PITS, call-by-value PITS and PITS with parallel reduction at the type-level. We show
the trade-offs between the simplicity and expressiveness for different reduction strategies.
• Unified subtyping: A novel technique that unifies typing and subtyping into a single
relation. This technique enables the development of expressive dependently typed calculi
with subtyping.
• The λI6 calculus: A dependently typed calculus with subtyping that employs unified
syntax, iso-types and unified subtyping. The calculus supports top types, higher-order
polymorphism and bounded quantification and can fully subsume System F6 . We provetransitivity of subtyping and type-safety for this calculus.
• Iso-Strong Sums: A novel treatment of dependent sums whose strong destructors are
typed as intermediate type-level applications. This makes it possible to use call-by-value
casts for required type-level computations.
• The λIΣ calculus: A dependently typed calculus with unified subtyping and iso-strongsums. This calculus supports impredicative polymorphism and retains desirable properties.
We prove transitivity of subtyping and type-safety for this calculus.
Outline of Thesis. The thesis is divided into two parts. The first part presents an informal
overview of iso-types by motivating examples (Chapter 3), and the formal theory of Pure Iso-Type
Systems (Chapter 4). It is the foundation of the thesis and provides a substantial theory for
iso-types. The second part further studies calculi with both iso-types and subtyping. It presents
two new calculi, i.e., the λI6 calculus with unified subtyping (Chapter 5) and the λIΣ calculus
with iso-strong sums (Chapter 6). In summary, the remaining chapters of this thesis are organized
as follows:
Chapter 2 provides several background knowledge for this thesis.
Chapter 3 gives an overview of iso-types. We discuss the motivation for the development of isotypes and informally introduce the basic mechanism of iso-types in PITS. We give examples
written in the surface language Fun to illustrate the usefulness and expressiveness of PITS.
Chapter 4 gives a formal presentation of Pure Iso-Type Systems (PITS), including three variantsof PITS that differ on the reduction strategy used in explicit casts. We present the formal

Chapter 1. Introduction

14

syntax, operational semantics and typing judgments. We develop metatheory for all variants
and prove both type-safety and decidability of type checking. We provide an extensive
comparison of PITS to a closely related calculus called PTSf [van Doorn et al. 2013].
Chapter 5 presents the λI6 calculus. We discuss the motivation of unified subtyping and present
an example of object encodings using λI6 . We formally present the specification of λI6 .
Two major results of the metatheory, namely transitivity of subtyping and type-safety areproved. We present a bidirectional version of λI6 and show the subsumption of System F6
in λI6 . We discuss several alternative designs of λI6 .
Chapter 6 presents the λIΣ calculus. We discuss the motivation of iso-strong sums and present
an example of encoding Scala-like traits using λIΣ . We present the formal specification of
λIΣ . We discuss its metatheory and prove major results including transitivity and typesafety. We also show Sig, a lightweight surface language over λIΣ with Scala-like traits forpresenting the application of strong dependent sums. We show a type-directed translationfrom Fun to λIΣ and prove its soundness.
Chapter 7 discusses the related work to PITS, λI6 and λIΣ .
Chapter 8 concludes the thesis and discusses potential directions for future work.
Mechanized Proofs and Prototype Implementation. All proofs in the thesis are machinechecked in Coq theorem prover [The Coq development team 2016], except for the completenessof λIΣ over System F6 and the translation soundness of Sig which can be found in Appendix A.
These proofs are manual due to the difficulties in mechanizing proofs between different typesystems [Kaiser et al. 2017]. For lemmas that are proved manually, we add a pencil symbol“.” in the title (e.g. Lemma 5.5.1). We also implement a prototype interpreter and compiler ofFun, a simple language which features algebraic datatypes and pattern matching by elaborating
to PITS. The mechanized proofs and the Fun implementation are available online at https://bitbucket.org/ypyang/archive.
Prior Publications.
as follows:

The content of this thesis is partially based on previously published papers• Yanpeng Yang, Xuan Bi, and Bruno C. d. S. Oliveira. 2016. Unified Syntax with Iso-types.
In Programming Languages and Systems, Atsushi Igarashi (Ed.). Springer International
Publishing, Cham, 251-270.
This paper is the basis of Chapter 3 and Chapter 4. The material of the paper is significantly
revised and expanded in the thesis. The calculus from the paper is further generalized to a familyof calculi with the PTS tradition called PITS. The study of call-by-value PITS and the completenessof full PITS to PTS are new in Chapter 4.
• Yanpeng Yang and Bruno C. d. S. Oliveira. 2017. Unifying Typing and Subtyping. Proc.
ACM Program. Lang. 1, OOPSLA, Article 47 (Oct. 2017), 26 pages. https://doi.org/10.1145/
3133871
This paper is the basis of Chapter 5. The study of the combination of unified subtyping andstrong sums is new in Chapter 6.

15

CHAPTER

2

BackgroundIn this chapter, we introduce several preliminaries on type theory which are basic concepts
for better understanding the thesis, including pure type systems (Section 2.1), dependent sums
(Section 2.2), iso-recursive types (Section 2.3), subtyping (Section 2.4) and path-dependent types(Section 2.5). Note that all topics introduced in this chapter are well-established and well-studied
concepts of type theory. Readers who are familiar with these topics can quickly go through thischapter. For readers who may not be familiar with notations of type theories, we recommend thebook Types and Programming Languages by Benjamin C. Pierce [2002] for a quick introduction.

2.1

Pure Type Systems

Pure Type Systems (PTS) [Barendregt 1991, 1992] are a generic framework to study a family oftype systems, including the simply typed lambda calculus (λ→), System F [Reynolds 1974; Girard
1972] (λ2) and the calculus of constructions (λC) [Coquand and Huet 1988]. PTS unifies terms andtypes (also kinds) into a single syntactic category. Thanks to the unified syntax, PTS has a very
concise presentation, which consists of only seven typing rules. Two of them are parameterized
by the specification of PTS, i.e., the axioms for typing sorts, and the rules for typing Pi-types.
By instantiating the specification, we can obtain a wide range of type systems, even logicallyinconsistent ones. The content of this section is heavily inspired by previous presentations of
PTS by Barendregt [1992] and Severi and de Vries [2012].

2.1.1

Basics of PTS

Specification. The specification of PTS is defined as follows [Severi and de Vries 2012]:
Definition 2.1.1 (Specification of PTS). PTS is specified by a triple S = (S, A, R) where
1. S is a set of constants called sorts;
2. A ⊆ S × S is a set of axioms;
3. R ⊆ S × S × S is a set of rules.
We use the metavariable s ∈ S to range over sorts. There is a special kind of PTS specification,
called the functional or singly-sorted specification:
Definition 2.1.2 (Functional Specification). A PTS specification is functional if

Chapter 2. Background16
1. If (s1 , s2 ) and (s1 , s02 ) are in A, then s2 = s02 .
2. If (s1 , s2 , s3 ) and (s1 , s2 , s03 ) are in R, then s3 = s03 .

The functional specification is useful to prove properties such as typing uniqueness and decidabilityof type checking for PITS, as discussed in Section 4.1.5.
Syntax.

In PTS, terms and types are defined in the same syntactic category:Definition 2.1.3 (Syntax of PTS). The syntax of PTS is defined bya, b, A, B ::= s | x | a b | λx : A. a | Πx : A. B
Γ::= ∅ | Γ, x : A
where a, b, A, B denote the pseudo-terms and Γ denotes the pseudo-contexts.
The variables are denoted by x, y, z, etc. Although there is no distinction between terms andtypes, by convention we still use lower-case meta-variables a, b, c, etc. to denote terms andupper-case meta-variables A, B, C, etc. to denote types. We use FV(a) for the set of free variables
in a. We use syntactic sugar A → B to denote Πx : A. B when x 6∈ FV(B), i.e., x does notoccur free in B. Given Γ = {x1 : A1 , . . . , xn : An }, the domain of the context is defined bydom(Γ) = {x1 , . . . , xn }.
Dynamic Semantics.
2012]:The beta-reduction of PTS is defined as follows [Severi and de Vries

Definition 2.1.4 (One-step Beta-reduction). Given the beta rule:(λx : A. b) aβ b[x 7→ a]

The one-step beta-reduction −→β is defined as the smallest relations on pseudo-terms that are closed
under the beta rule ( β ) and under contexts.
where the notation b[x 7→ a] denotes a capture-avoiding substitution that replaces all freeoccurrences of x in b with a. The relation −→β is inductively defined by applying the basecase, i.e., the beta rule ( β ), for every sub-term of a pseudo-term. Thus, we also call −→β fullbeta-reduction, since the beta rule can be applied at any position of a (pseudo) term. Based on−→β , we define the multi-step beta-reduction and beta-equivalence:
Definition 2.1.5 (Multi-step Beta-reduction). The multi-step beta-reduction β is the reflexivetransitive closure of −→β .
Definition 2.1.6 (Beta-equivalence). The beta-equivalence =β is the reflexive-symmetric-transitive
closure of −→β , i.e., the smallest equivalence relation containing −→β .
Typing Rules. A PTS determined by the specification S = (S, A, R) has the notation λS andis defined by the judgment Γ `S a : A, or simply Γ ` a : A. The notion of the judgment isdefined by typing rules shown in Figure 2.1.
The axiom rule checks the type of sorts, which states that the type of sort s1 is sort s2 if therelation (s1 , s2 ) is in the axiom set A. The start rule types the variable x according to the binding2.1. Pure Type Systems

17(axiom)∅ ` s1 : s2

if (s1 , s2 ) ∈ A(start)Γ`A:sΓ, x : A ` x : A

if x fresh in Γ

(weakening)

Γ`A:s
Γ`b:B
Γ, x : A ` b : B

if x fresh in Γ

(product)Γ ` A : s1
Γ, x : A ` B : s2
Γ ` (Πx : A. B ) : s3

if (s1 , s2 , s3 ) ∈ R(abstraction)

Γ, x : A ` b : BΓ ` (Πx : A. B ) : sΓ ` (λx : A. b) : (Πx : A. B )(application)Γ ` b : (Πx : A. B )Γ`a:AΓ ` b a : B[x 7→ a]Γ`a:A(conversion)

Γ`B:s
Γ`a:B

A =β B

Figure 2.1. Typing rules of PTS
x : A from the context. The weakening rule states that a typing judgment Γ ` b : B still holds
if the context is expanded with a well-formed binding x : A. Both start and weakening rules
require that the new variable x adding to the context Γ should be fresh, i.e., x ∈/ dom(Γ). The
product rule checks Pi-types and allows the binder type A, the body type B and the Pi-type itself
to have different sorts. The relation among these sorts, i.e., (s1 , s2 , s3 ), is defined by the rule set R.
The abstraction and application rules type check lambda abstractions and function applications,
respectively. Finally, the conversion rule allows converting types that are beta-equivalent.

2.1.2

Examples of PTS

We show several concrete examples of PTS by instantiating different specifications.
The Lambda Cube. The lambda cube [Barendregt 1992] contains eight type systems of typed
lambda calculi, as shown in Figure 2.2. The systems can be obtained by PTS specifications whereS = {?, 2}

A = {(?, 2)}

By convention, we use the abbreviation (s1 , s2 ) for (s1 , s2 , s2 ) ∈ R. Ranging s1 and s2 over{?, 2}, there are four possible values of (s1 , s2 ), denoted by
R0 = {(?, ?), (2, ?), (?, 2), (2, 2)}

Recalling the PTS typing rules for abstractions and products, each value represents a dependency
pattern of functions:Chapter 2. Background

18
λω

λ2

λC

λP 2

λω

λ→

λP ω

λP

Figure 2.2. The lambda cube

Rule(?, ?)(2, ?)(?, 2)(2, 2)

Dependency
terms depending on terms
terms depending on types
types depending on terms
types depending on types

Exampleordinary functions
polymorphic functions
dependent types
type constructors

Note that there are eight subsets of R0 containing the basic rule (?, ?), i.e., (?, ?) ∈ R ⊆ R0 ,which give us the exactly eight calculi of the lambda cube. Among all eight calculi, we introduce
four commonly used typed calculi:• The simply typed lambda calculus (λ→) is obtained by the PTS specification with thecommon S and A mentioned above, as well as R = {(?, ?)} which is the smallest subset
of rules.
• The second-order lambda calculus (λ2), also known as System F [Reynolds 1974; Girard
1972], has the rule set R = {(?, ?), (2, ?)}, and additionally allows polymorphic functions
over λ→.
• The higher-order polymorphic lambda calculus (λω), also known as System Fω [Girard 1972],
has the rule set R = {(?, ?), (2, ?), (2, 2)}, and further supports type constructors over
System F .
• The calculus of constructions (λC) [Coquand and Huet 1988] has the following rule set:R = {(?, ?), (2, ?), (2, 2), (?, 2)}which is the largest subset of R0 , i.e., R0 itself. λC further supports dependent types over
System Fω , which allow types to depend on terms.
Strongly Normalizing PTS. We have introduced the lambda cube that includes eight systems
that are specialized PTSs. One common property is that all eight calculi are strongly normalizing [Barendregt 1992]. The definition is as follows:
Definition 2.1.7 (Normalization).
1. A term a is weakly normalizing if there exists a term b in normal form such that a β b.

2.1. Pure Type Systems

19

2. A term a is strongly normalizing if all beta-reduction sequences starting from a are finite.
Definition 2.1.8 (Normalizing PTS). A PTS λS is strongly (weakly) normalizing if for all Γ ` a : A
we have that a and A are strongly (weakly) normalizing.
In general, if a type system is strongly normalizing, then it is consistent when viewed as a logic, i.e.,
it is logically consistent, meaning that there does not exist an absurd term of type False = Πx : ?. x .
On the other side, we say that a system is inconsistent if all types are inhabited [Barendregt 1992;
Girard 1972]. One can derive a term of False type in an inconsistent system.
Inconsistent PTS. There are PTS specifications that can generate inconsistent systems. One
well-known example is the λ? calculus [Barendregt 1992], which has the following PTS specification:
S = {?} A = {(?, ?)} R = {(?, ?)}There is only one axiom called the “type-in-type” axiom [Cardelli 1986b] that causes circularity
in typing sort, i.e. ? : ?. The inconsistency of λ? was first proved by Girard [1972]:
Theorem 2.1.1 (Girard’s Paradox). The type False = Πx : ?. x is inhabited in λ?, i.e. ∅ ` a :False for some a.
The calculus is not normalizing, due to the following lemma [Barendregt 1992]:
Lemma 2.1.1 (Absurd Has No Normal Form). Let λS be a PTS extending λ2. Suppose ∅ ` a : False.
Then a has no normal form.
By Girard’s theorem, we can find a term a such that Γ ` a : False in λ?. Such a has nonormal form and is not even weakly normalizing. Hence, the calculus is not weakly or strongly
normalizing.

2.1.3

Metatheory of PTS

We state several important results of PTS. The properties hold for arbitrary PTS, unless otherwise
stated. The following lemmas and theorems are from the work by Barendregt [1992] and proofs canbe found in Barendregt’s work or other related literature [van Benthem Jutting 1993; Barendregt
1991].
Lemma 2.1.2 (Substitution Lemma for PTS). If Γ, x : A, Γ0 ` b : B and Γ ` a : A, thenΓ, Γ0 [x 7→ a] ` b[x 7→ a] : B[x 7→ a].
Lemma 2.1.3 (Weakening Lemma for PTS). Let Γ and Γ0 be legal contexts such that Γ ⊆ Γ0 . IfΓ ` a : A, then Γ0 ` a : A.
Theorem 2.1.2 (Subject Reduction for PTS). If Γ ` a : A and a β a0 , then Γ ` a0 : A.
Theorem 2.1.3 (Decidability of Type Checking for Normalizing PTS). If S = (S, A, R) where S
is finite, let λS be a PTS that is (weakly or strongly) normalizing. Then given Γ and a, it is decidable
to check whether there exists an A such that Γ ` a : A or not.
Lemma 2.1.4 (Uniqueness of Types for Functional PTS). Let λS be a PTS that is functional. IfΓ ` a : A and Γ ` a : B, then A =β B.
Notice that the decidability of type checking (Theorem 2.1.3) requires a PTS to be weakly orstrongly normalizing. And the uniqueness of types (Lemma 2.1.4) requires a PTS to be functional(i.e. has a functional specification, see Definition 2.1.2).

Chapter 2. Background

20

2.2

Dependent Sums

A pair type, denoted by A × B, is one of the simplest compound types. A pair of type A × B
consists of two components where the first component has type A and the second has type B. Ina dependent type theory, pair types can also be extended with type dependency, similarly to howdependent function types (i.e. Pi-types Πx : A. B ) generalize non-dependent function types (i.e.
arrow types A → B). Such generalized pairs are called dependent sums where the type of thesecond component can depend on the first. Dependent sum types, denoted by Σx : A. B , are also
called Sigma-types. The typing rule of dependent sums is as follows:Γ ` e1 : AΓ ` e2 : B [x 7→ e1 ]Γ ` pack [e1 , e2 ] as (Σx : A. B ) : (Σx : A. B )where pack is the constructor of dependent sums. There are two forms of dependent sums,
namely weak and strong sums. The two forms are distinguished by their destructors [Schmidt
1994].

2.2.1

Weak Sums

Weak sums are eliminated by weak pattern matching, i.e. the unpack operator, which is conductedwithin a particular scope and the pattern variables x and y cannot escape this scope. The typing
rule for unpack is as follows:Γ ` e1 : Σx : A. B

Γ, x : A, y : B ` e2 : C

Γ`C :?

Γ ` unpack e1 as [x , y] in e2 : C
Notice that both x and y cannot occur free in C, since C is a well-formed type under the context
Γ without x or y. Weak sum types can also be encoded with Pi-types in a similar way to Churchencoding existential types in System F [Pierce 2002]:
Σx : A. B , Πz : ?. (Πx : A. B → z ) → z
z freshpack [e1 , e2 ] as Σx : A. B , λz : ?. λf : (Πx : A. B → z ). f e1 e2
z freshunpack e as [x, y] in e0 , e C (λx : A. λy : B . e 0 )x, y ∈/ FV(C)
where z is fresh such that z ∈/ FV(Πx : A. B ). Note that C is the type of e0 . A and B can bederived from the type of e, i.e., Σx : A. B.

2.2.2

Strong Sums

Strong sums are eliminated by projections similarly to non-dependent pairs, which directly extract
the first or second component without any scoping restriction. In particular, the type of the second
projection can refer to the first. The standard typing rules for the first and second projection are
as follows:Γ ` e : Σx : A. B
Γ ` e : Σx : A. B
Γ ` e.1 : AΓ ` e.2 : B [x 7→ e.1]

Note that x does not show (as a free variable) in the typing result of the second projection e.2,
since all occurrences of x are replaced by the first projection e.1.

2.3. Iso-Recursive Types

2.2.3

21

Comparison of Weak and Strong Sums

The projection operators of strong sums can be more expressive than the unpack operators of
weak sums. For example, recall the encoding of abstract integer sets using dependent sums shownin Section 1.3.3. In Scala, we can write a generic function f on Set:
def f(s: Set) = s.member(3, s.insert(3, s.empty()))

This function is encodable by the unpack operator:
f = λs : Set. unpack s as [T , s 0 ] in s 0 .member 3 (s 0 .insert 3 s 0 .empty)
It can also be encoded using projections:f = λs : Set. (s.2).member 3 ((s.2).insert 3 (s.2).empty)
where the pattern variable s 0 is replaced by a direct second projection s.2. However, consider
another generic function g that simply returns an empty set:
def g(s: Set) = s.empty()

We cannot encode g using unpack as follows:g = λs : Set. unpack s as [T , s 0 ] in s 0 .empty-- ill-typed

because s 0 .empty has type T which violates the typing rule of unpack. The type of the sub-termin an unpack should not refer to pattern variables. In contrast, we can encode g with the second
projection:g = λs : Set. (s.2).empty
The type of g is Π(s : Set). (s.1) which is well-formed by using the first projection to represent
the abstract type member.
Nonetheless, weak and strong sums both have their applications. Weak sums are usefulfor data abstraction [Mitchell and Plotkin 1988; Pierce 2002], while strong sums are suitable
for representing modular structures [MacQueen 1986]. It usually takes less effort to support
weak sums, since they are essentially polymorphic existential types which are encodable by
Pi-types in traditional dependently typed systems, e.g., the calculus of constructions [Coquandand Huet 1988]. On the contrary, strong sums are beyond the expressiveness of the plain calculusof constructions and cannot be Church-encoded with Pi-types [Cardelli 1986b].

2.3

Iso-Recursive Types

Recursive types are types that can refer to themselves. For example in Haskell, an integer list
type IntList is recursively defined:
data IntList = Nil | Cons Int IntList
The definition indicates that an IntList can be either an empty list (Nil ) or a concatenation of asingle integer (Int) and another integer list (IntList). Similarly, IntList can be defined as a classin Java, which can be viewed as a recursive type:Chapter 2. Background22
class IntList {Integer value;
IntList next;}

In type theory, a recursive type is denoted by µx : A. B . The µ-operator is an explicit
recursion operator. The binder x refers to the whole type itself, i.e., x = µx : A. B , and can show
up in the body type B. The previous IntList example can also be written with µ as follows [Pierce
2002]:
IntList = µx : ?. {Nil : Unit, Cons : Int × x }The binder x refers to IntList itself, which is a type, i.e., has kind ?. The body is a record type (i.e.
a named pair) consisting of two components Nil and Cons. The empty list case Nil is a singletonof Unit type. The concatenation case Cons is a pair consisting of a number and another list
whose type is x , equivalently IntList.

2.3.1

Iso-Recursive versus Equi-Recursive Types

Recursive types can represent infinite structures by constantly expanding the body. Givenµx : A. B , one can expand the body type B by unfolding, an operation that replaces all occurrencesof x in B by the whole µ-term itself:µx : A. B −→ B [x 7→ µx : A. B ]Such expansion/unfolding operation of recursive types can be performed either implicitly or
explicitly. Accordingly, there are two ways of formalizing recursive types in the literature, namely
the equi-recursive and iso-recursive approach [Crary et al. 1999]. Recursive types using such two
approaches are called equi-recursive and iso-recursive types.
Equi-Recursive Types. In the equi-recursive approach, the recursive type and its unfolded
type are definitionally equal, i.e., both types can be used interchangeably in any context. Thus, wehave the following equivalence relation:µx : A. B = B [x 7→ µx : A. B ]The benefit is that the equi-recursive treatment naturally allows type expressions to be infinite
as the unfolding operation happens automatically. However, it is difficult to type-check equirecursive types, since the type-checking algorithm usually does not work directly with infinite
types [Pierce 2002].
Iso-Recursive Types. Another approach, the iso-recursive approach, treats a recursive typeand its unfolding as different types, but isomorphic ones. One cannot replace a recursive typewith its unfolded form or vice versa. Instead, the unfolding or folding (the opposite of unfolding)operation is triggered explicitly by two operators, unfold and fold, respectively. For example,
assuming that there exist expressions e1 and e2 such that e1 : µx : A. B and e2 : B [x 7→ µx :

2.3. Iso-Recursive Types

23

A. B ], we have the following typing results:
unfold e1: B [x 7→ µx : A. B ]fold [µx : A. B ] e2 : µx : A. B
where fold and unfold map back and forth between the original and unfolded form. Formally, we
have the following standard typing rules of iso-recursive types [Pierce 2002]:

Γ ` e1 : (µx : A. B )Γ ` (µx : A. B ) : ?
Γ ` e2 : B [x 7→ µx : A. B ]Γ ` unfold e1 : B [x 7→ µx : A. B ]Γ ` fold [µx : A. B ]e2 : (µx : A. B )The isomorphism between types of e1 and e2 is witnessed by fold and unfold:
unfold−−*µx : A. B )
−−
−−
−−
−−
−−
−−
−
− B [x 7→ µx : A. B ]fold [µx :A. B ]The iso-recursive treatment makes it somewhat less convenient and intuitive to use recursive
types, since one needs to explicitly add unfold and fold instructions whenever conversions ofrecursive types are involved. On the other hand, type-checking iso-recursive types is much easierthan equi-recursive ones since the typing rules of unfold and fold are syntax-directed.

2.3.2

Iso-Recursive Types in Haskell

For practicality reasons, many programming languages implement recursive types using the
iso-recursive approach instead of the equi-recursive approach. For example, algebraic datatypes
in Haskell [Marlow et al. 2010] and ML [Milner et al. 1990] implicitly use iso-recursive types forrecursively defined structures, such as the previous IntList example. Similarly, Java implicitly
introduces a recursive type for the class definition and the method call of objects involves animplicit unfold operation [Pierce 2002].
In Haskell, one cannot directly define a recursive type using the type synonym:
type Bad = Int → Bad
The type synonym treats the types at two sides of = as equal, similarly to the equi-recursive
approach, which is however not supported in Haskell. Instead, one needs to use newtype (ordata) to wrap the unfolded form (i.e. the right-hand side type) inside a constructor:
newtype Good = MkGood (Int → Good )It is also possible to use newtype to define a generic fixpoint combinator for types:
newtype Fix f = Fold {unfold :: f (Fix f )}The type Fix is a type-level fixpoint using the iso-recursive approach. Its constructor Fold formsa recursive type from function f and destructor unfold forces the computation to obtain theunfolded form f (Fix f ). Such combinator can be used to model the recursion in datatypes anddefine them in a modular fashion, as illustrated in the Data Types à la Carte paper by Swierstra[2008].

Chapter 2. Background

24

2.4

Subtyping

Subtyping plays an important role in object-oriented programming (OOP) languages such Java
to model polymorphism. Subtyping is a relation between two types, denoted by A 6 B, where
A is called a subtype of B, and B is called a supertype of A. The relation means that wheneverthe context requires a term of type B, it can accept a term of type A. For example, in many
languages such as C/C++, the integer type can be considered as a subtype of a floating-point
number type, i.e. int 6 float. Whenever one needs a float, an int can be used, but not viceversa. Such interpretation of subtyping is often called the principle of safe substitution [Pierce
2002]. To connect typing with the subtyping relation, we need a new typing rule called thesubsumption rule:
Γ`e:A
A6B
Γ`e:B
This rule indicates that any term of type A is also a term of type B, which complies with theinterpretation of subtyping.

2.4.1

Important Subtyping Rules

We introduce several important subtyping rules that can be found in many languages.
Reflexivity and Transitivity. First, the subtyping relation should satisfy two basic properties:
reflexivity and transitivity, i.e., subtyping should be a reflexive relation by the following rule:
A6A
and a transitive relation by the following rule:
A6B

B 6C

A6C
Notice that the transitivity rule is not algorithmic in the sense that one needs to guess the type
B when applying the transitivity rule for A 6 C . When implementing a subtyping algorithm,
one usually needs to eliminate the transitivity rule and prove that it is admissible from othersubtyping rules [Pierce 2002; Pierce and Steffen 1997].
Function Types. In higher-order languages, functions are first-class values and can be passed
as arguments. Thus, we need a subtyping rule between function types:
B1 6 A1A 2 6 B2

A1 → A2 6 B1 → B2
Note that the subtype relation of the argument types is reversed. We call it contravariant. And
the subtype relation has the same order for the result types as the function types. We call such
relation covariant. The reason is that if a function has type A1 → A2 , it can take any argumentsof B1 which is a subtype of A1 and returns terms of type A2 which can be treated as having its
supertype B2 . Thus, we can treat any function of type A1 → A2 as having type B1 → B2 .

2.4. Subtyping

25

Record Types. Many languages support records, which are collections of named fields. The
record type is denoted by {l1 : T1 , · · · , ln : Tn } where li ranges over names. There are threetyping rules for record types [Pierce 2002]:• The width subtyping rule:{l1 : T1 , · · · , ln : Tn , · · · , ln+k : Tn+k } 6 {l1 : T1 , · · · , ln : Tn }which indicates that record types are subtypes if they have more fields at the end. Since
every field showing in the supertype also shows in the subtype, any operation accepted by
the supertype can be supported by the subtype.
• The depth subtyping rule:
Si 6 Ti∀i, 1 6 i 6 n{l1 : S1 , · · · , ln : Sn } 6 {l1 : T1 , · · · , ln : Tn }which indicates types of each corresponding fields are in the subtyping relation.
• The permutation subtyping rule:{li0 : Ti0 } is a permutation of {li : Ti }{l10 : T10 , · · · , ln0 : Tn0 } 6 {l1 : T1 , · · · , ln : Tn }which indicates that the order of fields does not matter.
Top Types. Finally, in some languages, there exists a type which is a supertype of any type.
We call it the top type, denoted by >. We need the following subtyping rule for the top type:
A6>
Many OOP languages have the top type which is usually the universal base class, e.g., Object inJava and Any in Scala.

2.4.2

Bounded Quantification

So far we have introduced the subtyping relation as a judgment A 6 B . Subtyping can also be
used with a quantifier to require the binder to be a subtype of a specific upper bound. We call thisbounded quantification. For example, System F6 [Cardelli et al. 1994] is an extension to System Fwith subtyping and bounded quantification. The specification of F6 is shown in Figure 2.3. In
F6 , we have one extra type abstraction with an upper bound:ΛX 6 T . t
where the binder X needs to be a subtype of type T . Correspondingly, the abstraction has abounded universal type:(ΛX 6 T . t) : (∀X 6 T . T 0 )Chapter 2. Background

26(Syntax)
Types
Terms
Contexts

T, U
t
∆

::=
::=
::=

X | > | T1 → T2 | ∀X 6 U . T
x | λx : T . t | t1 t2 | ΛX 6 T . t | t[T ]∅ | ∆, x : T | ∆, X 6 T∆`T(Type Well-formedness)

FWT-Top

FWT-Var

`∆
∆`>

`∆

X 6U ∈ ∆∆`X

FWT-Arrow

FWT-Forall∆ ` T1∆ ` T2∆ ` T1 → T2

∆ ` T1∆, X 6 T1 ` T2
∆ ` ∀X 6 T1 . T2`∆

(Context Well-formedness)
FW-Empty`∅

FW-Type

FW-Term`∆∆`T` ∆, X 6 T`∆∆`T` ∆, X : T∆`T 6U(Subtyping)

FS-Top

FS-VarRefl

FS-VarTrans∆`T∆`T 6>∆`X∆`X 6X

X 6 T1 ∈ ∆∆ ` T1 6 T2
∆ ` X 6 T2

FS-Arrow

FS-Forall∆ ` T1 6 U1
∆ ` U2 6 T2
∆ ` (U1 → U2 ) 6 (T1 → T2 )∆, X 6 U ` T1 6 T2
∆ ` (∀X 6 U . T1 ) 6 (∀X 6 U . T2 )∆`t :T(Typing)

FT-Var

FT-AbsFT-App`∆∆, x : T1 ` t : T2
∆ ` (λx : T1 . t) : T1 → T2

∆ ` t1 : T1 → T2
∆ ` t2 : T1
∆ ` t1 t2 : T2

x :T ∈ ∆∆`x :T
FT-TAbs

FT-TApp∆, X 6 T1 ` t : T2
∆ ` (ΛX 6 T1 . t) : (∀X 6 T1 . T2 )∆ ` t : (∀X 6 U1 . U2 )∆ ` T 6 U1
∆ ` t[T ] : U2 [X 7→ T ]FT-Sub∆`t :T∆`T 6U∆`t :U

Figure 2.3. Specification of System F6
The original unbounded quantification of System F can be viewed as a special case of top-bounded
quantification:∀X. T , ∀X 6 >. T
Variants of System F6 . There are two variants of System F6 , the Kernel Fun variant [Cardelliand Wegner 1985] and the Full variant [Cardelli et al. 1994]. Figure 2.3 shows the Kernel Fun
variant. The only difference between two variants is the subtyping rule of bounded universal

2.5. Path-Dependent Types

27

types. In the Kernel Fun variant, two bounded universal types can be compared only when theirbounds are identical, i.e., invariant:∆, X 6 U ` T1 6 T2
∆ ` (∀X 6 U . T1 ) 6 (∀X 6 U . T2 )In the Full variant, the bounds are contravariant, hence not required to be equal:∆ ` U2 6 U1∆, X 6 U2 ` T1 6 T2

∆ ` (∀X 6 U1 . T1 ) 6 (∀X 6 U2 . T2 )The subtyping rule of the Full variant seems more natural, which follows the treatment ofsubtyping function types. However, this rule makes Full F6 undecidable [Pierce 1992], meaningthat the algorithm implementing subtyping rules of Full F6 does not terminate for certain inputs.
On the contrary, Kernel Fun F6 is decidable by using the restricted invariant subtyping rule.
Thus, from the perspective of implementation, the Kernel Fun variant is more interesting since it
can have a decidable subtyping algorithm.

2.5

Path-Dependent Types

Scala [Odersky et al. 2004] supports path-dependent types [Odersky et al. 2003; Amin et al. 2014],
a weaker form of dependent types that only allow types to depend on paths. The syntax ofpath-dependent types (i.e. paths) can be formally defined as follows [Odersky et al. 2003]:
p ::= x | p.L
A path p is a variable x followed by a sequence of selections, e.g., x.L1 . · · · .Ln . In Dependent
Object Type (DOT) [Rompf and Amin 2016; Amin et al. 2016], a calculus that captures core featuresof Scala, paths are further simplified to only allow single selections:p ::= x.L
Meanwhile, paths are valid types:
T ::= · · · | pThus, paths can appear with other types such as universal types:∀(x : T ). (x.L)
A concrete example is the dependent method type of the generic method g from Section 2.2.3:
def g(s: Set) = s.empty()g: (s: Set)s.T

where the result type s.T can refer to the parameter s of the method.
Comparison with Full Dependent Types. The need of path-dependent types arises fromaccessing abstract type members of traits which involves some forms of value dependency (seealso Section 1.3.3). Scala takes a conservative approach by only supporting path dependency

Chapter 2. Background28

and avoids the need of supporting more general forms of dependent types. There are two majordifferences between path-dependent types and full dependent types from traditional dependently
typed calculi (e.g. the calculus of constructions [Coquand and Huet 1988]).
First, Pi-types can support dependency on any terms instead of only path dependency, e.g.,a vector type Vec n where n can be any natural number. Such vector types are not expressible
with path-dependent types. Moreover, with strong sums, Pi-types along with projections cansimulate path-dependent types. For example, in Section 2.2.3, the function g can be encoded withthe second projection and its type is a Pi-type with the first-projection: Π(s : Set). (s.1).
Second, traditional dependent types usually support arbitrary computations at the type level,
e.g., Vec (1 + 2) = Vec 3. In contrast, path-dependent types only support simple forms of typeconversions, such as instantiating abstract type members with actual types. Such type conversions
can be done with simple type equality relations. For example, if we apply an implementation of
Set to g such that T=List[Int], we will have:g(new Set {type T = List[Int]; ... }): List[Int]// excerpted

The original result type, i.e., the abstract type s.T, is instantiated with the actual type List[Int]according to the type equality T=List[Int].

29

Part I:
Pure Iso-Type Systems

31

CHAPTER

3

Overview of Iso-Types

In this chapter, we give an overview of iso-types and informally introduce key features of Pure
Iso-Type Systems (PITS). PITS enables the combination of unified syntax and general recursion,
while retains decidable type checking at the same time. The main source of inspiration for thedesign of PITS comes from iso-recursive types [Crary et al. 1999; Pierce 2002], which we briefly
introduced in Section 1.4.1. Instead of an implicit type conversion (employed by PTS), PITS
provides a generalization of iso-recursive types called iso-types. In PITS, not only folding/unfoldingof recursive types is explicitly controlled by term level constructs, but also any other type-levelcomputation (including beta reduction/expansion). This is somewhat similar to how datatypes
or newtypes are used in (classic) Haskell to explicitly trigger type-level computation for bothrecursive and non-recursive types.
There is an analogy to language designs with equi-recursive types and iso-recursive types. Withequi-recursive types, type-level recursion is implicitly folded/unfolded, which makes establishingdecidability of type-checking much more difficult. In iso-recursive designs, the idea is to tradesome convenience by a simple way to ensure decidability. Similarly, we view the design oftraditional dependently typed calculi, such as PTS, as analogous to systems with equi-recursive
types. In PTS, it is the conversion rule that allows type-level computation to by implicitly triggered.
However, the proof of decidability of type checking for PTS is non-trivial, as it depends on thenormalization property [van Benthem Jutting 1993]. Moreover decidability is lost when adding
general recursion. In contrast, the cast operators in PITS have to be used to explicitly trigger
each step of type-level computation, but it is easy to ensure decidable type-checking, even in thepresence of general recursion.
It is worth emphasizing the goal of PITS is to show the benefits of PTS-style unified syntax
in terms of economy of concepts for more traditional programming language designs, but not
to use unified syntax to express computationally intensive type-level programs. Traditional
functional languages only require basic use of type-level computation to support common features
like parametrized algebraic data types, iso-recursive types or purely functional objects [Pierce
and Turner 1994]. These features require only one or a small number of finite steps of typereductions/expansions where the iso-type approach fits well. In Section 3.2, we give examples toillustrate how such features of modern functional languages can be encoded with iso-types in
PITS.

Chapter 3. Overview of Iso-Types

32

3.1

Motivation and Overview

3.1.1

Implicit Type Conversion in Pure Type Systems

The typing rules for PTS contain a conversion rule [Barendregt 1991] (see also Section 2.1.1):Γ`e:A

A =β BΓ`e:B
This rule allows one to derive e : B from the derivation of e : A with the beta equality of A and
B . This rule is important to automatically allow terms with beta equivalent types to be considered
type-compatible. For example, consider the following identity function:f = λy : (λx : ?. x ) Int. y
The type of y is a type-level identity function applied to Int. Without the conversion rule, f cannot
be applied to 3 for example, since the type of 3 (Int) differs from the type of y ((λx : ?. x ) Int).
Note that the beta equivalence (λx : ?. x ) Int =β Int holds. Therefore, the conversion rule
allows the application of f to 3 by converting the type of y to Int.
Decidability of Type Checking and Strong Normalization. While the conversion rule in
PTS brings a lot of convenience, an unfortunate consequence is that it couples decidability oftype checking with strong normalization of the calculus [van Benthem Jutting 1993]. Therefore
adding general recursion to PTS becomes difficult, since strong normalization is lost. Due to theconversion rule, any non-terminating term would force the type checker to go into an infinite
loop (by constantly applying the conversion rule without termination), thus rendering the typesystem undecidable. For example, assume a term z that has type loop, where loop stands for any
diverging computation. If we type check (λx : Int. x ) z under the normal typing rules of PTS,
the type checker would get stuck as it tries to do beta equality on two terms: Int and loop, where
the latter is non-terminating.

3.1.2

Newtypes: Explicit Type Conversion in Haskell

Early designs of functional languages such as Haskell deliberately forbid implicit type conversions.
However, although not widely appreciated, since the very beginning Haskell (and other functional
languages) has supported explicit type-conversions via algebraic datatypes, or their simpler
sibling newtypes. In essence, encapsulated behind algebraic datatypes and newtypes is a language
mechanism that supports explicit type conversions. Such language mechanism is closely related
to iso-recursive types, as introduced in Section 2.3.2, but also allows for computations that are
not recursive.
In early versions of Haskell, such as Haskell 98, there is no real type-level computation as
in dependently-typed languages such as Coq [The Coq development team 2016]. In particular,
there are no computational type-level lambdas. Indeed Haskell forbids type-level lambdas to
avoid higher-order unification that is required in dependently typed languages such as Coq orAgda [Jones 1993]. While modern Haskell is half the way in evolving into a dependently typed
language, it still does not support type-level lambdas.

3.1. Motivation and Overview

33

Despite the absence of type-level lambdas, it is still possible to express type-level functions
via newtype or data constructs. For example, the type Id defined bynewtype Id a = MkId {runId :: a }can be viewed as a type-level identity function and Id a is isomorphic to type a. To convert thetype back and forth between a and Id a, one needs to explicitly use the constructor MkId or thedestructor runId :MkId :: a → Id a
runId :: Id a → a
While the explicit type level computations enabled by newtypes or algebraic datatypes are very
simple, they are essential for many of the characterizing programming styles employed in Haskell.
For example without such simple explicit type conversions it would not be possible to havethe monadic programming style that is available in Haskell, or modular interpreters enabled byapproaches such as Datatypes à la Carte [Swierstra 2008].

3.1.3

Iso-Types: Explicit Type Conversion in PITS

PITS iso-types have strong similarities with the explicit conversion mechanism found in languages
like Haskell, and iso-recursive types. Differently from Haskell (and similarly to iso-recursive
types) iso-types are purely structural, while Haskell datatypes and newtypes are nominal. Because
iso-types are structural they can be directly represented with type-level lambdas (and otherconstructs). Moreover, since in PITS type equality is just alpha-equality, type-level lambdas are
not problematic, since they do not trigger computation during type-checking.
Iso-types offer an alternative to the conversion rule of PTS, making it explicit as to when
and where to convert one type to another. Type conversions are explicitly controlled by two
language constructs: cast↓ (one-step reduction) and cast↑ (one-step expansion). One benefit of thisapproach is that decidability of type checking is no longer coupled with strong normalization of
the calculus. Another potential benefit is that the problem of type-inference may be significantly
simpler in a language with iso-types than in a language with a conversion rule. Although we do
not explore the later point in this thesis, Jones’ work on type-inference for higher-kinded types
in Haskell [Jones 1993] seems to back up this idea.
Reduction. The cast↓ operator allows a type conversion provided that the resulting type is areduction of the original type of the term. To explain the use of cast↓ , assume an identity function
g defined by g = λy : Int. y and a term e such that e : (λx : ?. x ) Int. In contrast to PTS, wecannot directly apply g to e in PITS since the type of e ((λx : ?. x ) Int) is not syntactically equal
to Int. However, note that the reduction relation (λx : ?. x ) Int ,→ Int holds. Therefore, we canuse cast↓ for the explicit (type-level) reduction:
cast↓ e : Int
Then the application g (cast↓ e) type checks.

Chapter 3. Overview of Iso-Types

34

Expansion. The dual operation of cast↓ is cast↑ , which allows a type conversion provided thatthe resulting type is an expansion of the original type of the term. To explain the use of cast↑ , let
us revisit the example from Section 3.1.1. We cannot apply f to 3 without the conversion rule.
Instead, we can use cast↑ to expand the type of 3:(cast↑ [(λx : ?. x ) Int] 3) : (λx : ?. x ) Int
Thus, the application f (cast↑ [(λx : ?. x ) Int] 3) becomes well-typed. Intuitively, cast↑ performs
expansion, as the type of 3 is Int, and (λx : ?. x ) Int is the expansion of Int witnessed by(λx : ?. x ) Int ,→ Int. Notice that for cast↑ to work, we need to provide the resulting type asargument. This is because for the same term, there may be more than one choice for expansion.
For example, 1 + 2 and 2 + 1 are both the expansions of 3.
One-Step. The cast operators allow only one-step reduction or expansion. If two type-levelterms require more than one step of reductions or expansions for normalization, then multiple casts
must be used. Consider a variant of the example such that e : (λx : ?. λy : ?. x ) Int Bool . Giveng = λy : Int. y, the expression g (cast↓ e) is ill-typed because cast↓ e has type (λy : ?. Int) Bool ,which is not syntactically equal to Int. Thus, we need another cast↓ :cast↓ (cast↓ e) : Intto further reduce the type and allow the program g (cast↓ (cast↓ e)) to type check.
Analogy to Newtypes in Haskell. By using cast operators, we can model the Haskell example
shown in Section 3.1.2:
Id = λx : ?. x
cast↑ [Id a ] : a → Id acast↓
: Id a → acast↑ and cast↓ are analogous to the datatype constructor MkId and destructor runId , respectively.
The difference is that PITS directly supports type-level lambdas without the need of using
newtype, though PITS only has alpha equality without implicit beta conversion. In somesense, type-level lambdas in PITS are non-computational as newtype-style “type functions” inHaskell. Nevertheless, we can still trigger type-level computation by casts, similarly to newtype
constructors and destructors in Haskell.
Decidability without Strong Normalization. With explicit type conversion rules the decidability of type checking no longer depends on the strong normalization property. Thus the typesystem remains decidable even in the presence of non-termination at type level. Consider thesame example using the term z from Section 3.1.1. This time the type checker will not get stuckwhen type checking (λx : Int. x ) z . This is because, in PITS, the type checker only performs
syntactic comparison between Int and loop, instead of beta equality. Thus it rejects the above
application as ill-typed. Indeed it is impossible to type check such application even with the use ofcast↑ and/or cast↓ : one would need to write infinite number of cast↓ ’s to make the type checker
loop forever (e.g., (λx : Int. x )(cast↓ (cast↓ . . . z))). But it is impossible to write such program inpractice which has an infinite length and cannot be stored with a finite capacity.

3.2. Iso-Types by Example

35

Variants of Casts. A reduction relation is used in cast operators to convert types. We study threepossible reduction relations: call-by-name reduction, call-by-value reduction and full reduction.
Call-by-name and call-by-value reduction cannot reduce sub-terms at certain positions (e.g., inside
λ or Π binders), while full reduction can reduce sub-terms at any position. We also create threevariants of PITS for each variant of casts. Specifically, full PITS uses a decidable parallel reduction
relation with full cast operators cast⇑ and cast⇓ . All variants reflect the idea of iso-types, but have
trade-offs between simplicity and expressiveness: call-by-name and call-by-value PITS use thesame reduction relation for both casts and evaluation to keep the system and metatheory simple,
but lose some expressiveness, e.g. cannot convert λx : Int. (1 + 1) to λx : Int. 2. Full PITS ismore expressive but results in a more complicated metatheory (see Section 4.3). Note that whengenerally referring to PITS, we do not specify the reduction strategy, which could be any variant.

3.1.4

General Recursion

PITS supports general recursion and allows writing unrestricted recursive programs at term level.
The recursive construct is also used to model recursive types at type level. Recursive terms andtypes are represented by the same µ primitive.
Recursive Terms. The primitive µx : A. e can be used to define recursive functions. For
example, the factorial function would be written as:fact = µf : Int → Int. λx : Int. if x == 0 then 1 else x × f (x − 1)
We treat the µ operator as a fixpoint, which evaluates µx : A. e to its recursive unfoldinge[x 7→ µx : A. e]. Term-level recursion in PITS works as in any standard functional language,e.g., fact 3 produces 6 as expected (see Section 4.1.4).
Recursive Types. The same µ primitive is used at the type level to represent iso-recursive
types [Crary et al. 1999]. In the iso-recursive approach a recursive type and its unfolding aredifferent, but isomorphic. The isomorphism is witnessed by two operations, typically called fold
and unfold (see also Section 2.3.1). In call-by-name PITS, such isomorphism is witnessed by cast↑and cast↓ . In fact, cast↑ and cast↓ generalize fold and unfold: they can convert any types, not justrecursive types, as we shall see in the example of encoding parametrized datatypes in Section 3.2.
To demonstrate the use of casts with recursive types, we show the formation of the “hungry”
type [Pierce 2002] H = µx : ?. Int → x . A term z of type H will accept one more integer every
time when it is unfolded by a cast↓ :(cast↓ z ) 3:Hcast↓ ((cast↓ z ) 3) 3
:Hcast↓ (. . . (cast↓ z ) 3 . . . ) 3 : H

3.2

Iso-Types by Example

PITS is a simple core calculus, but expressive enough to encode useful language constructs. In orderto show how features of modern functional languages can be encoded in PITS, we implemented asimple functional language Fun, a thin layer that is desugared to a specific PITS with only a single

Chapter 3. Overview of Iso-Types

36

sort ? and “type-in-type” axiom. We focus on common features available in traditional functional
languages and some interesting type-level features, but not the full power of dependent types. Fun
is not logically consistent due to the “type-in-type” axiom. In this section, we briefly introduce theimplementation of Fun and present interesting examples including algebraic datatypes (Section
3.2.1), higher-kinded types (Section 3.2.2), datatype promotion (Section 3.2.2), high-order abstract
syntax (Section 3.2.2) and object encodings (Section 3.2.3). All of those examples work in the 3variants of PITS. We also discuss one final example on dependently typed vectors (Section 3.2.4)that only works with parallel reduction. All examples can run in the prototype interpreter andcompiler (see Section 1.5).

3.2.1 Fun Implementation
Fun is built on top of a call-by-name PITS variant called λI [Yang et al. 2016] and provides
surface language constructs for algebraic datatypes and pattern matching. λI has the same PTS
specification as λ? (see Section 2.1.2), where S = {?}, A = {(?, ?)} and R = {(?, ?, ?)}. Algebraic datatypes and pattern matching in Fun are implemented using Scott encodings [Mogensen
1992], which can be later desugared into PITS (λI) terms. For demonstration, we implemented a
prototype interpreter and compiler for Fun, both written in GHC Haskell [Marlow 2010]. Fun
terms are firstly desugared into λI terms and then type-checked using PITS typing rules. The
type-checked λI terms can be evaluated directly by interpreter or compiled to JavaScript or
Haskell code.
Encoding Parametrized Algebraic Datatypes. We give an example of encoding parametrized
algebraic datatypes in PITS via the µ-operator and call-by-name casts. Importantly we shouldnote that having iso-recursive types alone (and alpha equality) would be insufficient to encode
parametrized types: the generalization afforded by iso-types is needed here.
In Fun we can define a polymorphic list as
data List a = Nil | Cons a (List a);This Fun definition is translated into PITS using a Scott encoding [Mogensen 1992] of datatypes:
List = µL : ? → ?. λa : ?. Πb : ?. b → (a → L a → b) → b
Nil = λa : ?. cast2↑ [List a ] (λb : ?. λn : b. λc : (a → List a → b). n)Cons = λa : ?. λx : a. λ(xs : List a).
cast2↑ [List a ] (λb : ?. λn : b. λc : (a → List a → b). c x xs)
The type constructor List is encoded as a recursive type. The body is a type-level function thattakes a type parameter a and returns a dependent function type, i.e., Π-type. The body of Π-type
is universally quantified by a type parameter b, which represents the result type instantiatedduring pattern matching. Following are the types corresponding to data constructors: b for Nil ,and a → L a → b for Cons, and the result type b at the end. The data constructors Nil andCons are encoded as functions. Each of them selects a different function from the parameters (nand c). This provides branching in the process flow, based on the constructors. Note that cast↑is used twice here (written as cast2↑ ): one for one-step expansion from τ to (λa : ?. τ ) a and theother for folding the recursive type from (λa : ?. τ ) a to List a, where τ is the type of cast2↑ body.

3.2. Iso-Types by Example

37

We have two notable remarks from the example above. Firstly, iso-types are critical for theencoding and cannot be replaced by iso-recursive types. Since type constructors are parametrized,
not only folding/unfolding recursive types, but also type-level reduction/expansion is required,
which is only possible with casts. Secondly, although casts using call-by-value and call-by-namereduction are not as powerful as casts using full beta-reduction, they are still capable of encoding
many useful constructs, such as algebraic datatypes and records. Nevertheless full-reduction
casts enable other important applications. Some applications of full casts are discussed later (seeSection 3.2.4).

3.2.2

Combining Algebraic Datatypes with Advanced Features

Languages like Haskell support several advanced type-level features. Such features, when usedin combination with algebraic datatypes, have important applications. Next we discuss someof these features and their applications. The purpose is to show all these advanced features are
encodable in PITS. For simplicity reasons, we use arrow syntax (x : A) → B as syntactic sugarfor Π-types Πx : A.B in the following text.
Higher-kinded Types. Higher-kinded types are type-level functions. To support higherkinded types, languages like Haskell use core languages that account for kind expressions. The
existing core language of Haskell, System FC [Sulzmann et al. 2007], is an extension of System
Fω [Girard 1972], which natively supports higher-kinded types. We can similarly constructhigher-kinded types in PITS. We show an example of encoding the functor “type-class” as a record:
data Functor (f : ? → ?) =Func {fmap : (a : ?) → (b : ?) → (a → b) → f a → f b };Note that in PITS, records are encoded using algebraic datatypes in a similar way as Haskell’srecord syntax [Marlow 2010]. Here we use a record to represent a functor, whose only field is afunction called fmap. The functor “instance” of the Maybe datatype is:data Maybe (a : ?) = Nothing | Just a;def maybeInst : Functor Maybe =Func Maybe (λa : ?. λb : ?. λf : a → b. λx : Maybe a.
case x ofNothing ⇒ Nothing b| Just (z : a) ⇒ Just b (f z ));After the translation process, the Functor record is desugared into a datatype with only one data
constructor (Func) that has type:(f : ? → ?) → (a : ?) → (b : ?) → (a → b) → f a → f b
Since Maybe has kind ? → ?, it is legal to apply Func to Maybe.
Datatype Promotion. Recent versions of Haskell introduced datatype promotion [Yorgey et al.
2012], in order to allow ordinary datatypes as kinds, and data constructors as types. With thepower of unified syntax, data promotion is made trivial in Fun. We show a representation of alabeled binary tree, where each node is labeled with its depth in the tree. Below is the definition:

Chapter 3. Overview of Iso-Types

38
data Nat = Z | S Nat;data PTree (n : Nat) = Empty| Fork (z : Int) (x : PTree (S n)) (y : PTree (S n));Notice how the datatype Nat is “promoted” to be used at the kind level in the definition of PTree.
Next we can construct a binary tree that keeps track of its depth statically:
Fork Z 1 (Empty (S Z )) (Empty (S Z ))If we accidentally write the wrong depth, for example:
Fork Z 1 (Empty (S Z )) (Empty Z )The above will fail to pass type checking.
Higher-order Abstract Syntax. Higher-order abstract syntax [Pfenning and Elliott 1988](HOAS) is a representation of abstract syntax where the function space of the meta-language isused to encode the binders of the object language. We show an example of encoding a simple
lambda calculus:
data Exp = Num Int| Lam (Exp → Exp)| App Exp Exp;
Note that in the lambda constructor (Lam), the recursive occurrence of Exp appears in a negative
position (i.e. in the left side of a function arrow). Systems like Coq [The Coq development team2016] and Agda [Norell 2007b] would reject such programs since it is well-known that suchdatatypes can lead to logical inconsistency. Moreover, such logical inconsistency can be exploited
to write non-terminating computations, and make type checking undecidable. In contrast, Fun isable to express HOAS in a straightforward way, while preserving decidable type checking.
Using Exp we can write an evaluator for the lambda calculus. As noted by Fegaras andSheard [Fegaras and Sheard 1996], the evaluation function needs an extra function (reify) toinvert the result of evaluation. The code for the evaluator is shown next (we omit most of theunsurprising cases; texts after “--” are comments):
data Value = VI Int | VF (Value → Value);data Eval = Ev {eval 0 : Exp → Value, reify 0 : Value → Exp };defrec ev : Eval =Ev (λe : Exp. case e of ... -- excerpted| Lam f ⇒ VF (λe 0 : Value. eval 0 ev (f (reify 0 ev e 0 )))(λv : Value. case v of ... -- excerpted| VF f ⇒ Lam (λe 0 : Exp. reify 0 ev (f (eval 0 ev e 0 )));
def eval : Exp → Value = eval 0 ev ;The definition of the evaluator is mostly straightforward. Here we create a record Eval , insidewhich are two name fields eval 0 and reify 0 . Similarly to the record syntax of Haskell, both eval 0
and reify 0 are also functions for projections of fields. The eval 0 function is conventional, dealing
with each possible shape of an expression. The tricky part lies in the evaluation of a lambda

3.2. Iso-Types by Example

39

abstraction, where we need a second function, called reify 0 , of type Value → Exp that lifts values
into terms. Thanks to the flexibility of the µ primitive, mutual recursion can be encoded by using
records.
Evaluation of a lambda expression proceeds as follows:
def show = λv : Value. case v of VI n ⇒ n;
def expr = App (Lam (λf : Exp. App f (Num 42))) (Lam (λg : Exp. g));show (eval expr ) -- returns 42

3.2.3

Object Encodings

Casts are useful for modeling examples other than algebraic datatypes. For example, we can modela simple form of object encodings with call-by-name cast operators. We present an example ofexistential object encodings [Pierce and Turner 1994] in Fun, which originally requires SystemFω . Note that the example here relies on the facility of algebraic datatypes and records in Fun. It
does not involve message passing due to the lack of subtyping in PITS. A more complete example
of object encodings will be shown in Section 5.1.5. First, we encode the existential type andits constructor in Fun by standard Church encoding [Pierce 2002] using the universal type (i.e.
Π-type):def Ex = λP : ? → ?. (z : ?) → ((x : ?) → P x → z ) → z ;def pack = λP : ? → ?. λe1 : ?. λe2 : P e1 .
cast↑ [Ex P ] (λz : ?. λf : (x : ?) → P x → z . f e1 e2 );where pack is the constructor to build an existential package, which is similar to the encoding ofpack operators for weak sums as introduced in Section 2.2.1. Thus, we can encode an existential
type ∃x. A as Ex (λx : ?. A) in Fun. The object type operator Obj can be encoded as follows:data Pair (A : ?) (B : ?) = MkPair {fst : A, snd : B };def Obj = λI : ? → ?. Ex (λX : ?. Pair X (X → I X ));where Pair A B encodes the pair type A × B. In the definition of Obj , the binder I denotes theinterface. The body is an existential type which packs a pair. The pair consists of a hidden state(with type X) and methods which are functions depending on the state (with type X → I X).
For a concrete example of objects, we use the interface of cell objects [Bruce et al. 1999]:
data Cell (X : ?) = MkCell {get : Int, set : Int → X , bump : X };The interface indicates that a cell object consists of three methods: a getter get to return thecurrent state, a setter set to return a new cell with a given state, and bump to return a new cellwith the state increased by one.
We can define a cell object c as follows:data Var = MkVar {getVar : Int };def CellT = λX : ?. Pair X (X → Cell X );def pair = MkPair Var (Var → Cell Var )(MkVar 0)-- Initial stateChapter 3. Overview of Iso-Types40(λs : Var . MkCell Var -- Methods(getVar s)(λn : Int.MkVar n)(MkVar (getVar s + 1)));
def p
def c

-- Method get-- Method set-- Method bump= pack CellT Var (cast↑ [CellT Var ] pair );= cast↑ [Obj Cell ] p;

The body of object c is an existential package p of type ΣX .Pair X (X → Cell X ) built
by the pack operator. The first parameter of pack is CellT that represents the body of theexistential type. The second parameter is the integer variable type Var which corresponds to theexistential binder X. The third parameter has type CellT Var which can be reduced to a pairtype Var × (Var → Cell Var ) which is defined in the definition pair constructed by MkPair .
The first component of the pair is the initial hidden state MkVar 0. The second component is afunction containing three methods that are defined in a record by MkCell and abstracted by thestate variable s. The definition of the three methods follows the cell object interface Cell .
Note that we have two cast↑ operators here: one over the existential package p and anotherover the pair . Due to the lack of a conversion rule in PITS, the desired type of the object c(i.e. Obj Cell ) is an application, which is different from the type of the existential package (i.e.
Ex CellT ). Noticing that
Obj Cell ,→ Ex (λX : ?. Pair X (X → Cell X )) = Ex CellT
We can use cast↑ to do one-step type expansion for the package. Similarly, the second cast↑operator used in the third parameter of pack converts the pair type into CellT Var . We emphasizethat the object encoding example exploits fundamental features of PITS, namely higher-kinded
types, higher-order polymorphism and explicit casts. The absence of a conversion rule does notprevent the object encoding because the required type-level computation is recovered by explicit
casts.

3.2.4 Fun with Full Reduction
So far all the examples can be encoded in Fun with casts using weak-head reduction. However
for some applications full reduction is needed at the type level. In this subsection particularly, weshow one such application. For brevity, we move types of arguments in def bindings to top-levelannotations without repeating them in λ-binders, e.g., we change def f = λx : Int. 1 into
def f : Int → Int = λx . 1

Leibniz Equality, Kind Polymorphism and Vectors. One interesting type-level feature of
GHC Haskell is generalized algebraic datatypes, or GADTs [Xi et al. 2003; Cheney and Hinze
2003; Peyton Jones et al. 2004]. GADTs require a non-trivial form of explicit type equality, which
is built in Haskell’s core language (System FC [Sulzmann et al. 2007]), called a coercion. PITS
does not have such built-in equality. However a form of equality can be encoded using Leibniz
Equality:
data Eq (k : ?) (a : k ) (b : k ) =Proof {subst : (f : k → ?) → f a → f b };

3.2. Iso-Types by Example

41

Note that the definition requires kind polymorphism: the kind of types a and b is k , which ispolymorphic and not limited to ?. For brevity, we use a ≡ b to denote Eq k a b by omitting thekind k . Then we can encode a GADT, for example, length-indexed list (or vector) as follows:data Vec (a : ?) (n : Nat) =Nil (Eq Nat n Z )| Cons (m : Nat) (Eq Nat n (S m)) a (Vec a m);
However, it is difficult to use such encoding approach to express the injectivity of constructors [Cheney and Hinze 2003], e.g., deducing n ≡ m from S n ≡ S m. It would be challenging
to encode the tail function of a vector:
def tail : (a : ?) → (n : Nat) → (v : Vec a (S n)) → Vec a n =λa. λn. λv . case v ofCons m p x xs ⇒ xs; -- ill-typed
The case expression above is ill-typed: xs has the type Vec a m, but the function requires thecase branch to return Vec a n. To convert xs to the correct type, we need to show n ≡ m. But
the equality proof p has type Eq Nat (S n) (S m), i.e., S n ≡ S m. Thus, the injectivity of
constructor S is needed.
Fun incorporates two full cast operators (cast⇑ and cast⇓ ) from full PITS. With the powerof full casts, we can “prove” the injectivity of S . We first define a partial function predNat todestruct S :def predNat : Nat → Nat =λn. case n of S m ⇒ m;Given S n ≡ S m, by congruence of equality, it is trivial to show predNat (S n) ≡ predNat (S m).
Noticing the reduction predNat (S n) ,→ n holds, we can use a full cast operator cast⇓ to reduce
both sides of the equality to obtain n ≡ m:
def injNat : (n : Nat) → (m : Nat) → Eq Nat (S n) (S m) → Eq Nat n m =λn. λm. λp. cast⇓ (lift Nat Nat (S n) (S m) predNat p);
The function lift (definition omitted) lifts the type of equality proof p from S n ≡ S m topredNat (S n) ≡ predNat (S m). Then cast⇓ converts it to Eq Nat n m (type annotations areomitted for brevity):p:S n ≡S mlift predNat p: predNat (S n) ≡ predNat (S m)cast⇓ (lift predNat p) : n ≡ m
We can finally write a well-typed version of tail :def castVec : (a : ?) → (n : Nat) → (m : Nat) →Eq Nat n m → Vec a m → Vec a n = ...; -- excerpted
def tail : (a : ?) → (n : Nat) → (v : Vec a (S n)) → Vec a n =λa. λn. λv . case v ofCons m p x xs ⇒ castVec a n m (injNat n m p) xs;

42

Chapter 3. Overview of Iso-Types

where castVec uses the proof n ≡ m to convert xs from Vec a m to Vec a n. Note that Fun is
not logically consistent and does not check whether the proof is terminating. However, it is easy
to see the injectivity proof injNat from the example above is total — though predNat is a partial
function, it is always applied to numbers with the form S n.

43

CHAPTER

4

Pure Iso-Type Systems

This chapter formally presents Pure Iso-Type Systems (PITS), a family of calculi which employs
unified syntax, supports general recursion and preserves decidable type-checking. PITS is comparable in simplicity to PTS. The main idea is to recover decidable type-checking through iso-types.
In PITS, every type-level computation step is explicit and each type-level reduction or expansion iscontrolled by a type-safe cast. Since single computation steps are trivially terminating, decidabilityof type checking is possible even in the presence of non-terminating programs at the type level.
At the same time term-level programs using general recursion work as in any conventional
functional languages, and can be non-terminating.
Such design choice is useful to serve as a foundation for functional languages that standin-between traditional ML-like languages and fully-blown dependently typed languages. In PITS,
recursion and recursive types are completely unrestricted and type equality is simply based onalpha-equality, just like traditional ML-style languages. However, like most dependently typed
languages, PITS uses unified syntax, naturally supporting many advanced type system features(such as higher-kinded types [Girard 1972], or kind polymorphism [Yorgey et al. 2012], see also
Section 3.2).
In this chapter, we study three different variants of PITS that differ on term evaluation strategy,
as well as the reduction strategy employed by the cast operators. They have different trade-offs interms of simplicity and expressiveness. Call-by-name PITS (Section 4.1) uses weak-head call-byname reduction, while call-by-value PITS (Section 4.2) enables standard call-by-value reduction
by employing a value restriction [Swamy et al. 2011; Sjöberg et al. 2012]. In both designs the
key idea is that the same reduction strategy is used for both term evaluation and type casts,
ensuring a consistent behavior1 of reduction at both type and term level. While such consistency
is easily ensured in a strongly normalizable calculus, as a term will always evaluate to the same
normal form regardless of the reduction strategy, this it is not true for PITS which enables generalrecursion and loses strong normalization. For example, given term (λx : Int. 1) ⊥, where ⊥ isany diverging computation, such term evaluates to 1 with call-by-name semantics, but diverges
with call-by-value semantics. In call-by-name/value PITS, we can trivially guarantee that noinvalid reasoning steps can happen due to mismatches with the evaluation strategy.
Unfortunately, both call-by-name and call-by-value reduction are not congruent for typeequivalence (e.g. λx : Int. 1 + 1 6,→ λx : Int. 2), which loses some expressiveness in terms oftype level computation. The third variant called full PITS (Section 4.3) uses parallel reduction for
1

Note that the consistency of behavior is not logical consistency, but meant for reduction relations.

Chapter 4. Pure Iso-Type Systems

44

casts. Full PITS is more expressive than call-by-name/value PITS, and its type-level reduction
is complete with respect to full beta-reduction employed by traditional PTS. Full PITS allows
equating terms such as Int → Vec (1 + 1) and Int → Vec 2 as equal, which is not possible
in call-by-name/value PITS. The price to pay for this more expressive and congruent design
is some additional complexity of the formalization, and the lack of consistency between term
and type level reduction2 (see Section 4.4.6). For all variants, type soundness and decidability of
type-checking are proved.
One key finding is that while using call-by-value or call-by-name reduction in casts loses some
expressive power for type-level computation, it allows those variants of PITS to have a simple anddirect operational semantics and proofs. In contrast, the variant of PITS with parallel reduction
retains the expressive power of PTS conversion, at the cost of a more complex metatheory wheretype-safety proofs must be shown indirectly by showing soundness/completeness to anothervariant of PTS. Similarly, many previous calculi including PTSf , a closely related calculus which isalso based on PTS and explicit type conversions, rely on other variants of PTS to provide dynamic
semantics and type-safety proofs. A detailed discussion of the trade-offs between the variants of
PITS, as well as PTSf , is given in Section 4.4.

4.1

Call-by-name Pure Iso-Type Systems

We formally present the first variant of Pure Iso-Type Systems. PITS is very close to Pure Type
Systems (PTS) [Barendregt 1992], except for two key differences: the existence of cast operatorsand general recursion. In this section, we focus on the call-by-name variant of PITS, which uses
a call-by-name weak-head reduction strategy in casts. We show type safety for any PITS and
decidability of type checking for a particular subset, i.e., functional PITS (see Definition 4.1.1).
One important remark is that the dynamic semantics of call-by-name PITS is given by a direct
small-step operational semantics, and type-safety is proved using the usual preservation andprogress theorems.

4.1.1

SyntaxFig. 4.1 shows the syntax of PITS, including expressions, values and contexts. Like Pure Type
Systems (PTS), PITS uses a unified representation for different syntactic levels. There is no
syntactic distinction between terms, types or kinds/sorts. Such unified syntax brings economy
for type checking, since one set of typing rules can cover all syntactic levels. As in PTS, PITS
contains a set of constants called Sorts, e.g., ?, 2, denoted by metavariable s. By convention, we
use metavariables A, B , etc. for an expression on the type-level position and e for one on theterm level. We use A → B as a syntactic sugar for Πx : A. B if x does not occur free in B .
Cast Operators. We introduce two new primitives cast↑ and cast↓ (pronounced as “cast up” and“cast down”) to replace the implicit conversion rule of PTS with one-step explicit type conversions.
The cast operators perform two directions of conversion: cast↓ is for the one-step reduction oftypes, and cast↑ is for the one-step expansion. The cast↑ construct needs a type annotation A as
For example, (λx : Int. 1 + 1) ⊥ is a non-terminating term under call-by-value reduction but can be reduced to(λx : Int. 2) ⊥ by parallel reduction.
2

4.1. Call-by-name Pure Iso-Type Systems
e, A, B

Expressionsv
ΓValuesContexts
Syntactic Sugar
A→B
castn↑ [A1 ] e,,castn↓ e,45
x | s | e1 e2 | λx : A. e | Πx : A. B
µx : A. e | cast↑ [A] e | cast↓ es | λx : A. e | Πx : A. B | cast↑ [A] e∅ | Γ, x : A

::=
|
::=
::=

Πx : A. B
where x 6∈ FV(B)cast↑ [A1 ](cast↑ [A2 ](. . . (cast↑ [An ] e) . . . ))where A1 ,→ A2 ,→ · · · ,→ An
cast↓ (cast↓ (. . . (cast↓ e) . . . ))
{z
}
|
n

Figure 4.1. Syntax of call-by-name PITS

the result type of one-step expansion for disambiguation, while cast↓ does not, since the resulttype of one-step reduction can be uniquely determined as discussed in Section 4.1.5.
We use syntactic sugar castn↑ and castn↓ to denote n consecutive cast operators (see Fig.
4.1). Alternatively, one can introduce them as built-in operators and treat one-step casts assyntactic sugar instead. Though using built-in n-step casts can reduce the number of individual
cast constructs, we do not adopt such alternative design in order to simplify the discussion ofmetatheory. Note that castn↑ is simplified to take just one type parameter, i.e., the last type A1of the n cast operations. Due to the determinacy of one-step reduction (see Lemma 4.1.2), theintermediate types can be uniquely determined and left out.
General Recursion. We use the µ-operator to uniformly represent recursive terms and types.
The expression µx : A. e can be used on the type level as a recursive type, or on term level asa fixpoint that is possibly non-terminating. For example, A can be a single sort s, as well as afunction type such as Int → Int or s1 → s2 .

4.1.2

Operational Semantics

Fig. 4.2 shows the small-step, call-by-name operational semantics. Three base cases include
rule R-Beta for beta reduction, rule R-Mu for recursion unfolding and rule R-CastElim forcast canceling. Two inductive cases, rule R-App and rule R-Castdn, define reduction at thehead position of an application, and the inner expression of cast↓ terms, respectively. Note thatrule R-CastElim and rule R-Castdn do not overlap because in the former rule, the inner term ofcast↓ is a value (see Fig. 4.1), i.e., cast↑ [A] e. In rule R-Castdn, the inner term is reducible andcannot be a value.
The reduction rules are called weak-head since only the head term of an application can be
reduced, as indicated by the rule R-App. Reduction is also not allowed inside the λ-term andΠ-term which are both defined as values. Weak-head reduction rules are used for both typeconversion and term evaluation. To evaluate the value of a term-level expression, we apply
the one-step (weak-head) reduction multiple times, i.e., multi-step reduction, the transitive andreflexive closure of the one-step reduction.

4.1.3

TypingFig. 4.3 gives the syntax-directed typing rules of PITS, including rules of context well-formedness` Γ and expression typing Γ ` e : A. Note that there is only a single set of rules for expression

Chapter 4. Pure Iso-Type Systems

46(Call-by-name Reduction)

e1 ,→ e2
R-App

e1 ,→ e10e1 e2 ,→ e10 e2

R-Beta(λx : A. e1 ) e2 ,→ e1 [x 7→ e2 ]R-Mu

µx : A. e ,→ e[x 7→ µx : A. e]

R-Castdn

e ,→ e 0
cast↓ e ,→ cast↓ e 0

R-CastElim

cast↓ (cast↑ [A] e) ,→ e

Figure 4.2. Operational semantics of call-by-name PITS
Γ`e:A

(Typing of Call-by-name PITS)
T-Abs

`Γ

Γ ` A : s1
Γ, x : A ` e : B
Γ, x : A ` B : s2
(s1 , s2 , s3 ) ∈ RΓ ` λx : A. e : Πx : A. B

T-Var

T-Ax

(s1 , s2 ) ∈ A
Γ ` s1 : s2

`Γ

x :A ∈ ΓΓ`x :A

T-ProdT-AppΓ ` e1 : Πx : A. B
Γ ` e2 : AΓ ` e1 e2 : B [x 7→ e2 ]

Γ ` A : s1
Γ, x : A ` B : s2
(s1 , s2 , s3 ) ∈ RΓ ` Πx : A. B : s3

T-Mu

T-Castup

T-Castdn

Γ`A:sΓ, x : A ` e : AΓ ` µx : A. e : AΓ`B :sΓ`e:A
B ,→ AΓ ` cast↑ [B ] e : BΓ`e:AA ,→ BΓ ` cast↓ e : B`Γ(Well-formedness)
W-Cons
W-Nil

`∅

Γ`A:s
x fresh in Γ
` Γ, x : A

Figure 4.3. Typing rules of call-by-name PITS

typing, as there is no distinction of different syntactic levels. Most typing rules are quite standard.
We write ` Γ if a context Γ is well-formed. We use Γ ` A : s to check if A is a well-formed type.
PITS is a family of type systems similarly to PTS, parametrized by the axiom set A ⊆ (S × S)
for typing sorts and rule set R ⊆ (S × S × S) for checking well-formedness of Π-types (seealso Section 2.1.1). Rule T-Ax checks whether sort s1 can be typed by sort s2 if (s1 , s2 ) ∈ A
holds. Rule T-Var checks the type of variable x from the valid context. Rule T-App and rule T-Abs
check the validity of application and abstraction respectively. Rule T-Prod checks the type wellformedness of the dependent function type by checking if (s1 , s2 , s3 ) ∈ R. Rule T-Mu checks thevalidity of a recursive term. It ensures that the recursion µx : A. e should have the same type A
as the binder x and also the inner term e.
Note that unlike the traditional presentation of PTS (see Figure 2.1), rule T-Abs does not rely
on rule T-Prod to check the well-formedness of Pi-types, but directly embeds the premises fromrule T-Prod. Several PTS-based calculi in the literature such as PTSf also use such a definition

4.1. Call-by-name Pure Iso-Type Systems

47

that can reduce dependencies between rules and simplify proofs of metatheory.
The Cast Rules. We focus on the rule T-Castup and rule T-Castdn that define the semantics
of cast operators and replace the conversion rule of PTS. The relation between the original andconverted type is defined by one-step call-by-name reduction (see Fig. 4.2). For example, given
a judgment Γ ` e : A2 and relation A1 ,→ A2 ,→ A3 , cast↑ [A1 ] e expands the type of e from
A2 to A1 , while cast↓ e reduces the type of e from A2 to A3 . We can formally give the typing
derivations of the examples in Section 3.1.3:
Γ ` e : (λx : ?. x ) Int(λx : ?. x ) Int ,→ IntΓ ` 3 : IntΓ ` (λx : ?. x ) Int : ?
(λx : ?. x ) Int ,→ Int

Γ ` (cast↓ e) : IntΓ ` (cast↑ [(λx : ?. x ) Int] 3) : (λx : ?. x ) Int

Importantly, in PITS term-level and type-level computation are treated differently. Term-levelcomputation is dealt in the usual way, by using multi-step reduction until a value is finallyobtained. Type-level computation, on the other hand, is controlled by the program: each step of
the computation is induced by a cast. If a type-level program requires n steps of computation toreach the normal form, then it will require n casts to compute a type-level value.
Syntactic Equality. Finally, the definition of type equality in PITS differs from PTS. Without
the conversion rule, the type of a term in PITS cannot be converted freely against beta equality,
unless using cast operators. Thus, types of expressions are equal only if they are syntacticallyequal (up to alpha renaming).

4.1.4

The Two Faces of Recursion

One key difference from PTS is that PITS supports general recursion for both terms and types. We
discuss general recursion on two levels and show how iso-types generalize iso-recursive types.
Term-level Recursion. In PITS, the µ-operator works as a fixpoint on the term level. By
rule R-Mu, evaluating a term µx : A. e will substitute all x ’s in e with the whole µ-term itself,
resulting in the unfolding e[x 7→ µx : A. e]. The µ-term is equivalent to a recursive function thatshould be allowed to unfold without restriction.
Recall the factorial function example in Section 3.1.4. By rule T-Mu, the type of fact is
Int → Int. Thus we can apply fact to an integer. Note that by rule R-Mu, fact will be unfolded toa λ-term. Assuming the evaluation of if -then-else construct and arithmetic expressions follows
the one-step reduction, we can evaluate the term fact 3 as follows:

,→
,→
,→

fact 3(λx : Int. if x == 0 then 1 else x × fact (x − 1)) 3 -- by rule R-App
if 3 == 0 then 1 else 3 × fact (3 − 1)-- by rule R-Beta· · · ,→ 6Note that we never check if a µ-term can terminate or not, which is an undecidable problem
for general recursive terms. The factorial function example above can stop, while there exist someterms that will loop forever. However, term-level non-termination is only a runtime concern andChapter 4. Pure Iso-Type Systems

48

does not block the type checker. In Section 4.1.5 we show type checking PITS is still decidable in
the presence of general recursion.
Type-level Recursion. On the type level, µx : A. e works as an iso-recursive type [Crary et al.
1999], a kind of recursive type that is not equal but only isomorphic to its unfolding (see also
Section 2.3.1). In PITS, we do not need to introduce fold and unfold operators, because with therule R-Mu, cast↑ and cast↓ generalize fold and unfold, respectively. Suppose that we have terms
e1 and e2 such that e1 : µx : A. B and e2 : B [x 7→ µx : A. B ]. The type of e2 is the unfolding of
e1 ’s type, which follows the one-step reduction relation by rule R-Mu:µx : A. B ,→ B [x 7→ µx : A. B ]By applying rule T-CastUp and rule T-Castdn, we can obtain the following typing results:
cast↓ e1
: B [x 7→ µx : A. B ]cast↑ [µx : A. B ] e2 : (µx : A. B )Thus, cast↑ and cast↓ witness the isomorphism between the original recursive type and its
unfolding, behaving in the same way as fold and unfold in iso-recursive types as in Section 2.3.1.
cast↓

−
*
µx : A. B −
)
−−
−−
−−
−−
−−
−−
−−
−
− B [x 7→ µx : A. B ]cast↑ [µx :A. B ]An important remark is that casts are necessary, not only for controlling the unfolding of recursive
types, but also for type conversion of other constructs, which is essential for encoding parametrized
algebraic datatypes (see Section 3.2.1).

4.1.5

Metatheory of Call-by-name PITS

We now discuss the metatheory of call-by-name PITS. We focus on two properties: the decidabilityof type checking and the type safety of the language. Firstly, we show that type checking for afunctional subset [Siles and Herbelin 2012] of PITS is decidable without requiring strong normalization. Secondly, any PITS is type-safe, proven by subject reduction and progress lemmas [Wrightand Felleisen 1994].
Decidability of Type Checking for Functional PITS. We limit the discussion in this paragraph to a subclass of PITS, functional PITS:
Definition 4.1.1. A PITS is functional if:
1. for all s1 , s2 , s02 , if (s1 , s2 ) ∈ A and (s1 , s20 ) ∈ A, then s2 ≡ s20 .
2. for all s1 , s2 , s3 , s03 , if (s1 , s2 , s3 ) ∈ R and (s1 , s2 , s30 ) ∈ R, then s3 ≡ s30 .
Such definition is the same as the one of functional PTS [Siles and Herbelin 2012], or singly-sorted
PTS [Barendregt 1992] (see also Section 2.1.1). Functional PITS enjoys uniqueness of typing, i.e.,
typing result is unique up to alpha equality:
Lemma 4.1.1 (Uniqueness of Typing for Functional PITS). In any functional PITS, if Γ ` e : A
and Γ ` e : B , then A ≡ B .

4.1. Call-by-name Pure Iso-Type Systems

49

For simplicity reasons, we only discuss decidability for functional PITS, where the proof canbe significantly simplified by the uniqueness of typing lemma. For non-functional PITS, one
may follow the proof strategy similarly used in non-functional PTS [van Benthem Jutting 1993],
by proving the “Uniqueness of Domains” lemma instead. We leave the decidability proof fornon-functional PITS as future work.
For functional PITS, the proof for decidability of type checking is by induction on the structureof e. The non-trivial case is for cast-terms with typing rule T-CastUp and rule T-Castdn. Bothrules contain a premise that needs to judge if two types A and B follow the one-step reduction, i.e.,
if A ,→ B holds. We show that B is unique with respect to the one-step reduction, or equivalently,
reducing A by one step will get only a sole result B . Such property is given by the following
lemma:
Lemma 4.1.2 (Determinacy of One-step Call-by-name Reduction). If e ,→ e1 and e ,→ e2 , thene1 ≡ e2 .
We use the notation ≡ to denote the alpha equivalence of e1 and e2 . Note that the presence ofrecursion does not affect this lemma: given a recursive term µx : A. e, by rule R-Mu, there always
exists a unique term e 0 ≡ e[x 7→ µx : A. e] such that µx : A. e ,→ e 0 . With this result, we showthat it is decidable to check whether the one-step relation A ,→ B holds. We first reduce A by
one step to obtain A0 (which is unique by Lemma 4.1.2), and compare if A0 and B are syntacticallyequal. Thus, we can further show type checking cast-terms is decidable.
By the definition of functional PITS, checking the type of sorts and well-formedness of Πtypes are decidable. For other cases, type checking is decidable by the induction hypothesis anduniqueness of typing (see Lemma 4.1.1). Thus, we can conclude the decidability of type checking3 :Theorem 4.1.1 (Decidability of Type Checking for Functional PITS). In any functional PITS,
given a well-formed context Γ and a term e, it is decidable to determine if there exists A such thatΓ ` e : A.
We emphasize that when proving the decidability of type checking, we do not rely on strong
normalization. Intuitively, explicit type conversion rules use one-step call-by-name reduction,
which already has a decidable checking algorithm according to Lemma 4.1.2. We do not need tofurther require the normalization of terms. This is different from the proof for PTS which requires
the language to be strongly normalizing [van Benthem Jutting 1993]. In PTS the conversion
rule needs to examine the beta equivalence of terms, which is decidable only if every term has anormal form.
Type Safety for all PITS. Type safety holds for any PITS, not just functional PITS. The proofof the type safety is by showing subject reduction and progress lemmas [Wright and Felleisen
1994]:
Theorem 4.1.2 (Subject Reduction of Call-by-name PITS). If Γ ` e : A and e ,→ e0 thenΓ ` e 0 : A.
Theorem 4.1.3 (Progress of Call-by-name PITS). If ∅ ` e : A then either e is a value v or there
exists e 0 such that e ,→ e 0 .
3This theorem is also called decidability of typability [Barendregt 1992, Section 4.4] where the typing result A is
not given and constructed by the typing algorithm.

Chapter 4. Pure Iso-Type Systems

50

The proof of subject reduction is straightforward by induction on the derivation of Γ ` e : A
and inversion of e ,→ e0 . Some cases need supporting lemmas: rule R-CastElim requires Lemma
4.1.2; rule R-Beta and rule R-Mu require the following substitution lemma:
Lemma 4.1.3 (Substitution of Call-by-name PITS). If Γ1 , x : B , Γ2 ` e1 : A and Γ1 ` e2 : B ,then Γ1 , Γ2 [x 7→ e2 ] ` e1 [x 7→ e2 ] : A[x 7→ e2 ].
The proof of progress is also standard by induction on ∅ ` e : A. Notice that cast↑ [A] e is avalue, while cast↓ e1 is not: by rule R-Castdn, e1 will be constantly reduced until it becomes avalue that could only be in the form cast↑ [A] e by typing rule T-Castdn. Then rule R-CastElim
can be further applied and the evaluation does not get stuck. Another notable remark is thatwhen proving the case for application e1 e2 , if e1 is a value, it could only be a λ-term but nota cast↑ -term. Otherwise, suppose e1 has the form cast↑ [Πx : A. B ] e10 . By inversion, we have∅ ` e10 : A0 and Πx : A. B ,→ A0 . But such A0 does not exist because Πx : A. B is a value which
is not reducible.

4.2

Call-by-value Pure Iso-Type Systems

Pure Iso-Type Systems enjoy the flexibility of choosing different reduction rules for type conversion
or term evaluation. In this section, we present another variant of PITS which uses call-by-value
reduction, a more commonly used reduction strategy. All metatheory presented in Section 4.1,
including type safety and decidability of typing, still holds for this variant. Call-by-value isinteresting because, for applications, the arguments are reduced before beta reduction. Such
reduction is problematic for dependent functions types in a setting with iso-types. We address
this problem by using a form of value restriction, inspired by previous work [Swamy et al. 2011;
Sjöberg et al. 2012].

4.2.1

Value Restriction

Call-by-value reduction (,→v ) requires the argument of beta reduction to be a value (v). A typicalleftmost reduction strategy of an application is that, one first reduces the function part to a value,then further reduces the argument. Such process is witnessed by the following reduction rules:

RV-AppL
RV-Beta(λx : A. e) v ,→v e[x 7→ v ]RV-AppR

e1 ,→v e10

e ,→v e 0

e1 e2 ,→v e10 e2

v e ,→v v e 0

A function in PITS can be dependent. That is the function type can depend on the argument.
For example, suppose that f is a dependent function generating a length-indexed list with given
length n, with the following type:f : (Πn : Int.Vec n)
By rule RV-AppR, the reduction f (1 + 1) ,→v f 2 holds. However, the types of two sides of the
reduction are different:f (1 + 1) : Vec (1 + 1)
f2
: Vec 2

4.2. Call-by-value Pure Iso-Type Systems

51

Notice that PITS does not contain an implicit conversion rule. Without an explicit type conversion,
subject reduction does not hold. There are at least two possible ways to deal with this issue: 1)
introducing a type cast for reduction; 2) requiring the dependent function to be applied to a value
only. For simplicity reasons, we choose the second method: a value restriction. The first method
entangles types with reduction, which makes the semantics more complicated.
Typing Rules with Value Restriction. Now we have two typing rules for the function application:

TV-AppV

TV-AppΓ `v e : Πx : A. B

Γ `v v : AΓ `v e v : B [x 7→ v ]Γ `v e1 : A → BΓ `v e2 : AΓ `v e1 e2 : B

If a function is dependent the argument must be a value (v). Otherwise, the function is nondependent and there is no restriction on its argument. Recall that the arrow type is syntactic
sugar for the non-dependent Π-type (see Figure 4.1). Note that these two typing rules overlap:
the Π-type of e in rule TV-AppV could be non-dependent. In such case, B = B [x 7→ v ] andrule TV-AppV has the same typing result as rule TV-App. Thus, such overlapping does not cause
any determinacy issues.
Two Sides of Value Restriction. Imposing such value restriction in PITS has both pros andcons. On one side, type-safety proofs are quite simple (see Section 4.2.3). We can safely ruleout the case that breaks type preservation when reducing the argument of a dependent function
application. Recalling the example above, a reduction like f (1 + 1) ,→v f 2 is not possible sincef (1 + 1) will be rejected by the type system in the first place. The argument (1 + 1) of thedependent function f is not a value, so f (1 + 1) is not a well-typed term. Thus, if a function
is applied to a reducible argument it must be a non-dependent function in order to ensure typepreservation.
Though users can easily write f 2 as a workaround to satisfy the type system instead off (1 + 1), there is no alternative way to express terms such as f (x + y) where the argument
cannot be reduced to a value. Thus, the value restriction makes the type system become more
restrictive on dependent function applications — users can only provide values but not arbitraryarguments to dependent functions. Nonetheless, there is no restriction on applying non-dependentfunctions to arguments, e.g., id (x + y) where id = λz : Int. z . In other words, there is no lossof expressiveness with respect to non-dependently typed programming.
Alternative to the Value Restriction. Instead of the value restriction, one could simultaneously add casts when reducing dependent function applications. Supposing we drop the value
restriction, for the same example of f , noticing that Vec (1 + 1) ,→v Vec 2, we can obtainf2: Vec 2cast↑ [Vec (1 + 1)](f 2) : Vec (1 + 1)
Then, f (1 + 1) ,→v cast↑ [Vec (1 + 1)](f 2) preserves the type with an extra cast↑ . However,such reduction relation involves types due to the annotation of casts. For simplicity reasons, weChapter 4. Pure Iso-Type Systems

52

leave this extension as future work (see Section 8.2) and stick to value restriction for a simpler
meta-theory.

4.2.2

Reduction with Open Terms

In call-by-value PITS, cast operators also use one-step call-by-value reduction to perform typeconversions. Open terms that contain free variables may occur during reduction, e.g., (λx :Int. x ) y, where y is a free variable. Using the rule RV-Beta, the reduction can only be performed
if y is a value. To allow beta reduction of such open terms, we allow variables as values. Traditionalcall-by-value calculi do not have such definitions, since reduction is used for term evaluation
but not type conversion. Nevertheless, several call-by-value calculi that involve type conversion
allow treating variables as values, such as Fireball Calculus [Paolini and Della Rocca 1999], as
well as several open call-by-value calculi [Accattoli and Guerrieri 2016], and Zombie [Sjöberg et al.
2012; Casinghino et al. 2014]. To make such definition work, we need to ensure that a variable issubstituted with a value. The rule RV-Beta already ensures such requirement.
Recursion and Recursive Types. For a recursive term µx : A. e, its unfolding has the forme[x 7→ µx : A. e] such that the substituted term is the term itself. Thus, we need to treat µ-terms
as values as in traditional call-by-value settings. One consequence is that a µ-term now is only
unfolded when it is placed at the function part of an application, or inside cast↓ :RV-Mu

RV-Castdn-Mu(µx : A. e) v ,→v (e[x 7→ µx : A. e]) v

cast↓ (µx : A. e) ,→v cast↓ (e[x 7→ µx : A. e])Thus, µ-terms only represents term-level recursive functions, as in most call-by-value languages.
They cannot directly represent recursive types at the same time. This is different from the call-byname PITS where µ-terms are both term-level fixpoints and recursive types, since substituted
terms are not necessarily values. Nevertheless, one can still recover recursive types in call-byvalue PITS by feeding the type-level recursive function a dummy argument, e.g., the unit value():
PITS Variant Recursive Type
Reduction
Call-by-name f = µy : A. e
f ,→ e[y 7→ f ]Call-by-value f 0 = µx : Unit → A. e[y 7→ x ()] f 0 () ,→v (e[y 7→ x ()][x 7→ f 0 ]) ()where x does not occur free in e. The recursive type f in call-by-name PITS can be simulated bya type-level recursive function f 0 applied to a dummy argument, i.e., f 0 ().
Finally, we show the full definition of call-by-value PITS in Figure 4.4. The changes from thecall-by-name variant are highlighted.

4.2.3

Metatheory

All the metatheory of call-by-name PITS still holds in the call-by-value variant, including two
key properties: type safety and decidability of type checking. The proofs are almost the same.
The only relevant change is the statement of the substitution lemma:

4.2. Call-by-value Pure Iso-Type Systems

53(Syntax)e, A, B

Expressionsv
ΓValuesContexts

x | s | e1 e2 | λx : A. e | Πx : A. B | µx : A. ecast↑ [A] e | cast↓ e
x | s | λx : A. e | Πx : A. B | µx : A. e | cast↑ [A] v∅ | Γ, x : A

::=
|
::=
::=

(Call-by-value Reduction)

e1 ,→v e2

RV-AppL
RV-BetaRV-Mu(λx : A. e) v ,→v e[x 7→ v ](µx : A. e) v ,→v (e[x 7→ µx : A. e]) v

e1 ,→v e10
e1 e2 ,→v e10 e2

RV-AppR

RV-Castup

RV-Castdn

e ,→v e 0v e ,→v v e 0

e ,→v e 0
cast↑ [A] e ,→v cast↑ [A] e 0

e ,→v e 0
cast↓ e ,→v cast↓ e 0

RV-Castdn-Mu
RV-CastElim

cast↓ ( µx : A. e ) ,→v cast↓ ( e[x 7→ µx : A. e] )cast↓ (cast↑ [A] v ) ,→v v

Γ `v e : A(Typing of Call-by-value PITS)
TV-Abs

TV-Ax

TV-Var`v Γ`v Γ(s1 , s2 ) ∈ A
Γ ` v s1 : s2

Γ `v A : s1
Γ, x : A `v e : B
Γ, x : A `v B : s2
(s1 , s2 , s3 ) ∈ RΓ `v λx : A. e : Πx : A. B

x :A ∈ ΓΓ `v x : A

TV-AppTV-AppVΓ `v e1 : A → BΓ `v e2 : AΓ `v e : Πx : A. B

Γ `v e1 e2 : BΓ `v v : AΓ `v e v : B [x 7→ v ]TV-ProdΓ `v A : s1
Γ, x : A `v B : s2
(s1 , s2 , s3 ) ∈ RΓ `v Πx : A. B : s3

TV-Mu

Γ `v A : s
Γ, x : A `v e : AΓ `v µx : A. e : A

TV-CastupΓ `v B : s

TV-CastdnΓ `v e : A

B ,→v AΓ `v e : AΓ `v cast↑ [B ] e : B

A ,→v BΓ `v cast↓ e : B`v Γ(Well-formedness)
WV-Cons
WV-Nil`v ∅Γ `v A : sx fresh in Γ`v Γ, x : A

Figure 4.4. Call-by-value PITS
Lemma 4.2.1 (Substitution of Call-by-value PITS). If Γ1 , x : B , Γ2 `v e : A and Γ1 `v v : B ,then Γ1 , Γ2 [x 7→ v ] `v e[x 7→ v ] : A[x 7→ v ].
We now require substituted terms to be values. With such a change, type preservation of reducing
open terms is possible, as discussed in Section 4.2.2. Such restricted substitution lemma is sufficientChapter 4. Pure Iso-Type Systems

54

for proving subject reduction, because all substituted terms are values in reduction rules (seeFigure 4.4). The subject reduction and progress lemmas can be proved in a similar way tocall-by-name PITS:
Theorem 4.2.1 (Subject Reduction of Call-by-value PITS). If Γ `v e : A and e ,→v e0 thenΓ `v e 0 : A.
Theorem 4.2.2 (Progress of Call-by-value PITS). If ∅ `v e : A then either e is a value v or there
exists e 0 such that e ,→v e 0 .
Like call-by-name reduction, the one-step call-by-value reduction is deterministic:
Lemma 4.2.2 (Determinacy of One-step Call-by-value Reduction). If e ,→v e1 and e ,→v e2 , thene1 ≡ e2 .
Similarly, for functional PITS, we have typing uniqueness and decidable type checking:Lemma 4.2.3 (Uniqueness of Typing for Functional PITS). In any functional PITS, if Γ `v e : A
and Γ `v e : B , then A ≡ B .
Theorem 4.2.3 (Decidability of Type Checking for Functional PITS). In any functional PITS,
given a well-formed context Γ and a term e, it is decidable to determine if there exists A such thatΓ `v e : A.

4.3

Iso-Types with Full Casts

In Sections 4.1 and 4.2, we have introduced two variants of PITS that use one-step call-byname/value reduction for both term evaluation and type conversion. The use of those reduction
strategies simplifies the design and metatheory, at the cost of some expressiveness (e.g. cannot
encode the vector example in Section 3.2.4). To gain extra expressiveness, we take one step further
to generalize casts with full reduction. In this section, we present a third variant of PITS called full
PITS, where casts use a decidable parallel reduction relation for type conversion. The trade-off issome extra complexity in the metatheory. We show that full PITS has decidable type checking andtype safety that holds up to erasure. The proofs and metatheory design is inspired by approaches
used in Zombie [Sjöberg and Weirich 2015] and Guru [Stump et al. 2008].

4.3.1

Full Casts with Parallel Reduction

Cast operators in call-by-name/value PITS use the same one-step reduction as term evaluation
for type-level computation. We refer to them as weak casts, because they lack the ability to do
full type-level computation where reduction can occur at any position of terms. For example,
weak casts cannot convert the type Vec (1 + 1) to Vec 2, because 1) for call-by-name reduction,
the desired reduction is at the non-head position; 2) for call-by-value reduction, the term is
rejected due to the value restriction. Thus, we generalize weak casts to full casts (cast⇑ and cast⇓ )utilizing a one-step decidable parallel reduction (,→p ) relation for type conversion. Figure 4.5 shows
the definition of ,→p . This relation allows reducing terms at any position, including non-head
positions or inside binders, e.g., λx : Int. 1 + 1 ,→p λx : Int. 2. Thus full type-level computation
for casts is enabled.

4.3. Iso-Types with Full Casts

55(Decidable Parallel Reduction)

r1 ,→p r2

P-App
P-Red

P-Var

P-Sort(λx : R. r1 ) r2 ,→p r1 [x 7→ r2 ]x ,→p xs ,→p s

P-Abs

P-ProdR ,→p R 0
r ,→p r 0
λx : R. r ,→p λx : R 0 . r 0

R1 ,→p R10
R2 ,→p R20
Πx : R1 . R2 ,→p Πx : R10 . R20

r1 ,→p r10
r2 ,→p r20
r1 r2 ,→p r10 r20
P-MuRedµx : R. r ,→p r [x 7→ µx : R. r ]P-Mu

R ,→p R 0
r ,→p r 0
µx : R. r ,→p µx : R 0 . r 0

Figure 4.5. One-step decidable parallel reduction of erased terms|e|(Term Erasure)|x||s||e1 e2 ||λx : A. e||Πx : A. B||µx : A. e||cast⇑ [A] e||cast⇓ [A] e|= x= s= |e1 | |e2 |= λx : |A|. |e|= Πx : |A|. |B|= µx : |A|. |e|
= |e|
= |e|

|Γ|

(Context Erasure)|∅|=|Γ, x : A| =∅|Γ|, x : |A|

Figure 4.6. Erasure of casts

There are three remarks for parallel reduction worth mentioning. Firstly, parallel reduction isdefined up to erasure denoted by |e| (see Figure 4.6), a process that removes all casts from term e.
We also extend erasure to context denoted by |Γ|. It is feasible to define parallel reduction only
for erased terms because casts in full PITS (also call-by-value PITS) are only used to ensure thedecidability of type checking and have no effect on dynamic semantics, thus are computationallyirrelevant. Note that casts in call-by-name PITS do not have this property, as we define cast↑ [A] e
to be a value. If we erase the cast operator, e can be further reducible, which changes the dynamic
semantics. In full (call-by-value) PITS, cast⇑ [A] v (cast↑ [A] v ) is a value and becomes v after
erasure, which is still a value and does not change the computational behavior.
We use metavariables r and R to range over erased terms and types, respectively. The only
syntactic change of erased terms is that there is no cast. The type system after erasure is essentiallya variant of PTS with recursion. We call it PTSµ . The syntax and semantics of PTSµ is shown in
Figure 4.7.

Chapter 4. Pure Iso-Type Systems

56(Syntax)
Expressions
ValuesContexts

r, R
u
∆

::=
::=
::=

x | s | r1 r2 | λx : R. r | Πx : R1 . R2 | µx : R. rs | λx : R. r | Πx : R1 . R2
∅ | ∆, x : R(Weak-head Reduction)

r1 ,→ r2
RE-Appr1 ,→ r10
r1 r2 ,→ r10 r2

RE-Beta(λx : R. r1 ) r2 ,→ r1 [x 7→ r2 ]RE-Mu

µx : R. r ,→ r [x 7→ µx : R. r ]∆`r :R(Typing of PTSµ )TE-Abs`∆∆ ` R1 : s1∆, x : R1 ` r : R2∆, x : R1 ` R2 : s2
(s1 , s2 , s3 ) ∈ R∆ ` λx : R1 . r : Πx : R1 . R2

TE-VarTE-Ax(s1 , s2 ) ∈ A∆ ` s1 : s2`∆

x :R ∈ ∆∆`x :R

TE-Prod
TE-App∆ ` r1 : Πx : R1 . R2
∆ ` r2 : R1
∆ ` r1 r2 : R2 [x 7→ r2 ]∆ ` R1 : s1∆, x : R1 ` R2 : s2
(s1 , s2 , s3 ) ∈ R∆ ` Πx : R1 . R2 : s3

TE-Mu

TE-Conv∆`R:s∆, x : R ` r : R∆ ` µx : R. r : R∆ ` r : R1

∆ ` R2 : s∆ ` r : R2`∆

R 1 ≡β R 2(Well-formedness)
WE-Cons
WE-Nil`∅∆`R:sx fresh in Γ` ∆, x : R

Figure 4.7. PTSµ
Secondly, the definition of parallel reduction in Figure 4.5 is slightly different from the standard
one for PTS [Adams 2006]. It is partially parallel: rule P-Red and rule P-MuRed do not parallel
reduce sub-terms, but only do beta reduction and recursion unfolding, respectively. The confluence
property for one-step reduction is lost4 . Nevertheless, such definition makes the decidability
property (see Lemma 4.3.5) easier to prove than the conventional fully parallel version, thus it iscalled decidable parallel reduction. It also requires fewer reduction steps than the non-parallelversion, thus correspondingly needs fewer casts.
Thirdly, parallel reduction does not have the determinacy property like weak-head reduction(Lemma 4.1.2). For example, for the term (λx : Int. 1 + 1) 3, we can (parallel) reduce it toeither (λx : Int. 2) 3 by rule P-App and rule P-Abs, or 1 + 1 by rule P-Red. Thus, to ensure thedecidability, we also need to add the type annotation for cast⇓ operator to indicate what exact
type we want to reduce to. Similarly to cast⇑ , cast⇓ [A] v is a value, which is different from the
Notice that multi-step reduction ,→→p is still confluent since it is equivalent to multi-step full beta reduction −→∗β(see Lemma 4.3.3) which is confluent.
4

4.3. Iso-Types with Full Casts

57(Syntax)e, A, B

Expressions

ΓContexts

::=
|
::=

x | s | e1 e2 | λx : A. e | Πx : A. B
µx : A. e | cast⇑ [A] e | cast⇓ [A] e∅ | Γ, x : AΓ `f e : A(Typing of Full PITS)
TF-Abs`f ΓΓ `f A : s1
Γ, x : A `f e : B
Γ, x : A `f B : s2
(s1 , s2 , s3 ) ∈ RΓ `f λx : A. e : Πx : A. B

TF-Var

TF-Ax(s1 , s2 ) ∈ AΓ `f s1 : s2`f Γx :A ∈ ΓΓ `f x : A

TF-Prod
TF-AppΓ `f e1 : Πx : A. B
Γ `f e2 : AΓ `f e1 e2 : B [x 7→ e2 ]Γ ` f A : s1
Γ, x : A `f B : s2
(s1 , s2 , s3 ) ∈ RΓ `f Πx : A. B : s3
TF-Castup

TF-MuΓ `f A : s
Γ, x : A `f e : AΓ `f µx : A. e : AΓ `f B : sΓ `f e : A|B | ,→p |A|Γ `f cast⇑ [B ] e : B

TF-CastdnΓ `f B : sΓ `f e : A|A| ,→p |B |

Γ `f cast⇓ [B ] e : B`f Γ(Well-formedness)
WF-Cons
WF-Nil`f ∅Γ `f A : sx fresh in Γ`f Γ, x : A

Figure 4.8. Full PITS

call-by-name/value variant.
Figure 4.8 shows the specification of full PITS. Changes from call-by-name/value PITS are
highlighted. Note that we do not define operational semantics directly but up to erasure. Reduction
relations are defined in PTSµ only for terms after erasure. Similarly, syntactic values are notdefined in full PITS but defined for erased terms, ranged over by u in PTSµ (see Figure 4.7).
This is different from call-by-name/value PITS, where reduction rules for type casting and term
evaluation are the same, i.e., the one-step call-by-name/value reduction. In full PITS, parallel
reduction is only used by casts, while a separate reduction is used for term evaluation. For
simplicity reasons, we choose the call-by-name reduction (,→) for term evaluation for erased
terms in PTSµ (see Figure 4.7).

4.3.2

Metatheory

We show that the two key properties, type safety and decidability of type checking, still hold infull PITS.

Chapter 4. Pure Iso-Type Systems

58
r1 −→β r2(Full Reduction)

B-Red(λx : R. r1 ) r2 −→β r1 [x 7→ r2 ]B-App1

B-App2

r1 −→β r10
r1 r2 −→β r10 r2

r2 −→β r20
r1 r2 −→β r1 r20

B-Abs1

B-Abs2

B-Prod1

R −→β R 0
λx : R. r −→β λx : R 0 . r

r −→β r 0
λx : R. r −→β λx : R. r 0

R1 −→β R10
Πx : R1 . R2 −→β Πx : R10 . R2
B-Mu1

B-Prod2

R2 −→β R20
Πx : R1 . R2 −→β Πx : R1 . R20

B-MuRedµx : R. r −→β r [x 7→ µx : R. r ]R −→β R 0
µx : R. r −→β µx : R 0 . rB-Mu2r −→β r 0
µx : R. r −→β µx : R. r 0

Figure 4.9. Full beta reduction
Type Safety. Full casts are more expressive but also complicate the metatheory: term evaluation
could get stuck using full casts. For example, the following term,(cast⇓ [Int → Int] (λx : ((λy : ?. y) Int). x )) 3
cannot be further reduced because the head position is already a value but not a λ-term. Notethat weak casts do not have such problem because only cast↑ is annotated and it is not legal tohave a Π-type in the annotation (see last paragraph of Section 4.1.5). To avoid getting stuck by
full casts, one could introduce several cast push rules similar to System FC [Sulzmann et al. 2007].
For example, the stuck term above can be further evaluated by pushing cast⇓ into the λ-term:(cast⇓ [Int → Int] (λx : ((λy : ?. y) Int). x )) 3 ,→ (λx : Int. x ) 3
However, adding “push rules” significantly complicates the reduction relations and metatheory.
Instead, we adopt the erasure approach inspired by Zombie [Sjöberg and Weirich 2015] andGuru [Stump et al. 2008] that removes all casts when proving the type safety. The typing of erased
terms follow the type system PTSµ (see Figure 4.7). The typing judgment is ∆ ` r : R where ∆ranges over the erased context.
PTSµ is a variant of PTS with recursion. We follow the standard proof steps for PTS [Barendregt
1992]. The substitution and progress lemmas are stated as follows:
Lemma 4.3.1 (Substitution of PTSµ ). If ∆1 , x : R 0 , ∆2 ` r1 : R and ∆1 ` r2 : R 0 , then
∆1 , ∆2 [x 7→ r2 ] ` r1 [x 7→ r2 ] : R[x 7→ r2 ].
Theorem 4.3.1 (Progress of PTSµ ). If ∅ ` r : R then either r is a value u or there exists r 0 suchthat r ,→ r 0 .
Notice that term evaluation uses the weak-head reduction ,→. We only need to prove subject
reduction and progress theorems for ,→. But we generalize the result for subject reduction, whichholds up to the parallel reduction ,→p . We first show subject reduction holds for one-step full

4.3. Iso-Types with Full Casts

59

beta reduction −→β (see Figure 4.9) and multi-step full beta reduction −→∗β , i.e., reflexive andtransitive closure of −→β :Lemma 4.3.2 (Subject Reduction for Full Beta Reduction).
then ∆ ` r 0 : R.

1. If ∆ ` r : R and r −→β r 0

2. If ∆ ` r : R and r −→∗β r 0 then ∆ ` r 0 : R.
Then we show −→∗β is equivalent to multi-step parallel reduction ,→→p , i.e., transitive closure of,→p (since it is already reflexive):
Lemma 4.3.3 (Equivalence of Parallel Reduction). Given r1 and r2 , r1 −→∗β r2 holds if and only
if r1 ,→
→p r2 holds.
Thus, subject reduction for parallel reduction ,→p is an immediate corollary:
Theorem 4.3.2 (Subject Reduction for Parallel Reduction). If ∆ ` r : R and r ,→p r 0 then∆ ` r 0 : R.
Finally, given that the PTSµ is type-safe, if we want to show the type-safety of full PITS, it issufficient to show the typing is preserved after erasure:Lemma 4.3.4 (Soundness of Erasure). If Γ `f e : A then |Γ| ` |e| : |A|.
Decidability of Type Checking. The proof of decidability of type checking full PITS is similar
to call-by-name PITS in Section 4.1.5. We also limit discussion of decidability to functional
PITS (see Definition 4.1.1). The only difference is for cast rule TF-Castup and rule TF-Castdn,
which use parallel reduction |A1 | ,→p |A2 | as a premise. We first show the decidability of parallel
reduction:
Lemma 4.3.5 (Decidability of Parallel Reduction). Given r1 and r2 , it is decidable to determine
whether r1 ,→p r2 holds.
The proof is by induction on the length of r1 and does not rely on the single-step confluence of,→p . The confluence of ,→p is lost due to two base reduction rules P-Red and P-MuRed, which do
not simultaneously reduce sub-terms but only do one-step beta reduction and recursive unfolding,respectively (see Section 4.3.1). However, both rules become deterministic, which makes it easier todetermine if ,→p in both cases. We can just check if one-step reduction of r1 is equal to r2 , similarly
to the proof for call-by-name PITS (see Section 4.1.5). For example, consider r1 = (λx : R3 . r3 ) r4
and r2 = r5 r6 . If case P-App applies, i.e., λx : R3 . r3 ,→p r5 and r4 ,→p r6 hold, then r1 ,→p r2
holds trivially. Otherwise, r1 ,→p r2 holds if and only if P-Red holds. The latter can be determinedby testing the equality of r3 [x 7→ r4 ] and r5 r6 . By contrast, the proof will be much complicatedfor the standard parallel reduction. To ensure one-step confluence, the rule P-Red becomes
r1 ,→p r10

r2 ,→p r20(λx : R. r1 ) r2 ,→p r10 [x 7→ r20 ]We now need to determine if r3 ,→p r30 holds or not. This is non-trivial since the induction
hypothesis only gives the hint whether λx : R3 . r3 ,→p r5 holds but not directly for r3 .

Chapter 4. Pure Iso-Type Systems

60(Typing of PTSstep )∆r :R
TS-Abs∆∆  R1 : s1∆, x : R1  r : R2∆, x : R1  R2 : s2
(s1 , s2 , s3 ) ∈ R∆  λx : R1 . r : Πx : R1 . R2

TS-VarTS-Ax(s1 , s2 ) ∈ A∆  s1 : s2

∆

x :R ∈ ∆∆x :R

TS-Prod
TS-App∆  r1 : Πx : R1 . R2
∆  r2 : R1
∆  r1 r2 : R2 [x 7→ r2 ]∆  R1 : s1∆, x : R1  R2 : s2
(s1 , s2 , s3 ) ∈ R∆  Πx : R1 . R2 : s3

TS-mu

TS-Betaup∆R:s∆, x : R  r : R∆  µx : R. r : R∆  r : R1

∆  R2 : s∆  r : R2

R2 −→β R1TS-Betadn∆  r : R1

∆  R2 : s∆  r : R2

R1 −→β R2(Well-formedness)∆
WS-Cons
WS-Nil∆R:sx fresh in Γ ∆, x : R∅Figure 4.10. Typing rules of PTSstep
As cast⇑ and cast⇓ are annotated, both A1 and A2 can be determined and the well-typedness
is checked in the original system. By Lemma 4.3.4, the erased terms keep the well-typedness.
By Lemma 4.3.5, it is decidable to check if |A1 | ,→p |A2 |. We conclude the decidability of typechecking by following lemmas:
Lemma 4.3.6 (Uniqueness of Typing for functional PITS). In any functional PITS, if Γ `f e : A1
and Γ `f e : A2 , then A1 ≡ A2 .
Theorem 4.3.3 (Decidability of Type Checking for functional PITS). In any functional PITS,
given a well-formed context Γ and a term e, it is decidable to determine if there exists A such thatΓ `f e : A.

4.3.3

Completeness to Pure Type Systems

We have shown that full PITS is complete to a variant of PTSµ . Such variant uses an alternative
single-step conversion rule [Geuvers 1995]:

TS-Betadn

TS-Betaup∆  r : R1

∆  R2 : s∆  r : R2

R2 −→β R1∆  r : R1

∆  R2 : s∆  r : R2

R1 −→β R2

4.4. Discussion

61

where −→β denotes full beta reduction (see Figure 4.9). We call this variant PTSstep (see Figure 4.10).
Its typing judgment is denoted by ∆  r : R. PITS can be seen as an annotated version of PTSstep .
We first show that full PITS is complete to PTSstep :Lemma 4.3.7 (Completeness of Full PITS to PTSstep ). If ∆  r : R, then there exists Γ,e and A
such that Γ `f e : A where |Γ| = ∆, |e| = r and |A| = R.
Furthermore, Siles and Herbelin have proved that single-step conversion rule is equivalent to
the original conversion rule using beta conversion in PTS (see Corollary 2.9 in [Siles and Herbelin
2012]). We have the following relation between PTSstep and PTSµ :Lemma 4.3.8 (Completeness of One-step PTS to PTS). If ∆ ` r : R, then ∆  r : R holds.
Thus, we can conclude the full PITS is complete to PTSµ :Theorem 4.3.4 (Completeness of Full PITS to PTSµ ). If ∆ ` r : R, then there exists Γ, e, A suchthat Γ `f e : A where |Γ| = ∆, |e| = r and |A| = R.

4.4

Discussion

We have developed PITS with the aim of using such family of calculi as foundations to programming languages supporting unified syntax and recursion. PITS trades the convenience of implicit
type conversion that is afforded in most dependently typed calculi by a simple meta-theory thatallows for decidable type-checking. Closely related to our work is PTS with explicit convertibility
proofs (PTSf ) [van Doorn et al. 2013], which is a variant of PTS that replaces the conversion ruleby embedding explicit conversion steps into terms. PTSf has strong connections to PITS in thesense that both systems are based on Pure Type Systems and require explicit type conversions —PTSf uses proof-annotated terms, while PITS uses cast operators. Although PTSf was motivatedby applications to theorem proving, PTSf (like PTS) can be instantiated to form inconsistentcalculi, which can encode fixpoints and general recursion. Therefore PTSf could also, in principle,
be used as a foundation for programming languages. However, the underlying mechanisms andfoundations of PTSf and PITS are different. Generally speaking, when dealing with programming
languages with general recursion it is important to study not only the static semantics, but also
the dynamic semantics. Unlike strongly normalizing languages where any choice of reduction
leads to termination, in languages that are not strongly normalizing this is not usually the caseand the choice of reduction is important. Furthermore the choice of the style of reduction in casts
has a profound impact on the properties and metatheory of the language. Our work on PITS
puts great emphasis on the study of the dynamic semantics and the trade-offs between different
choices, while in PTSf only the static semantics is studied. In the rest of this section, we give a
detailed comparison on features between PTSf and the three variants of PITS, summarized inTable 4.1. Other closely related work will be discussed in Section 7.1.

4.4.1

Direct Dynamic Semantics

One important difference between call-by-value and call-by-name PITS and the variant with full
reduction is that the former two calculi have a direct small-step operational semantics, while thesemantics of the later calculus is indirectly given by elaboration. A direct operational semantics
has the advantage that the reduction rules can be used to directly reason about expressions inChapter 4. Pure Iso-Type Systems

62

Table 4.1. Comparison between PTSf and PITS
Features

PTSf

Direct Dynamic Semantics#
Direct Proofs#
No Mutually Dependent Judgments #Implicit Proofs by Reduction#
Full Type-Level Computation
Consistency of Reduction—
Decidability with Recursion#
G2
SLOC of Coq proofs
7318
Lemmas of Coq proofs
319
1
2

Call-by-name
PITS

Call-by-value
PITS

Full PITS
#
#
G1

#

#

1217
62

1477
66

#
3796
221

Proofs for typing decidability are direct, but not for type-safety.
We believe that decidability should hold, but no there is no discussion or proofs in the formalization of
PTSf [van Doorn et al. 2013].

the calculus. This reasoning can be used to perform, for example, equational reasoning steps or
to justify the correctness of some optimizations. In an elaboration-based semantics the lack of
reduction rules means that one must first translate the source expression into a corresponding
expression in the target calculus, and then do all reasoning there. This is a much more involved
process.
As discussed in Section 4.3.2, it is difficult to directly define a type-preserving operationalsemantics for full PITS. The problem is not intrinsic to PITS, but rather it is a general problem
whenever full reduction is used in cast-like operators. Indeed this problem has been identified
previously in the literature [Sjöberg et al. 2012; Sulzmann et al. 2007], and two major approaches
have been used to address it. One approach is not to use a direct semantics but instead to use anelaboration semantics, which is precisely the approach that we used in our variant of PITS withfull reduction. This approach is quite common and it is also the approach used in PTSf as well as
several other calculi [Sjöberg et al. 2012; Sjöberg and Weirich 2015; Stump et al. 2008]. Anotherapproach that has been presented in the literature is to use push rules as in System FC [Sulzmann
et al. 2007; Yorgey et al. 2012; Weirich et al. 2013] and System DC [Weirich et al. 2017]. However
push rules significantly complicate the reduction rules (see Section 4.3.2).
In this work we show a third approach to achieve a simple type-preserving direct dynamic
semantics: we can use alternative weaker reduction relations (call-by-value or call-by-name) for
type conversion. The weaker reduction relations are straightforward and do not have the extra
complication of the push rules (although some expressiveness is lost).
There is no discussion on how to achieve direct dynamic semantics using the proof term
approach by PTSf , since they use an elaboration approach. Furthermore this is unlikely to betrivial. We expect that it may be possible to give a direct operational semantics to full PITS or PTSf
using push rules similar to the ones employed in System DC [Weirich et al. 2017], but this would
come at the cost of a much more involved set of reduction rules (as well as the corresponding
meta-theory) (see Section 8.2).

4.4.2

Direct Proofs

Because of the direct dynamic semantics it is possible to do direct proofs of preservation andprogress in call-by-value and call-by-name PITS. The meta-theory of Full PITS is significantly

4.4. Discussion

63

more involved because we need a target calculus and to prove several lemmas in both the target
and the source, as well as showing the correspondence between the two systems. To give a roughidea of the complexity of the different developments, Table 4.1 shows the total number of lines of
Coq code used and lemmas used to formalize the three variants of PITS. Roughly speaking thedevelopment of full PITS requires twice as many SLOC and nearly four times more lemmas thanthe other two variants, since we also need to formalize PTSµ along with full PITS.
PTSf is shown to be equivalent to plain PTS and its type-safety then can be guaranteed byshowing the correspondence to plain PTS [Barendregt 1991]. However the proof for soundness
and completeness between PTSf and PTS is highly non-trivial [van Doorn et al. 2013; Siles andHerbelin 2012]. In PTSf there is no discussion on proving subject reduction directly in PTSf . The
type-safety of PTSf is indirectly shown by erasure of explicit proofs to generate valid plain PTS
terms. This is similar to the proof strategy for type-safety of full PITS, which is shown up to
erasure of casts (see Section 4.3.2). The formalization of PTSf requires about 7000 SLOC and 300
lemmas (see Table 4.1), including auxiliary systems such as plain PTS and PTSe . These numbers
cannot be directly compared to the numbers of the PITS formalizations, since different approaches
and libraries are employed to deal with binding and the formalization of PTSf does not include
proofs of decidability of type-checking. Nevertheless the numbers are useful to give an idea ofthe effort in the PTSf formalization.
Ultimately we believe that direct proofs and a direct operational semantics of the call-by-nameand call-by-value PITS are quite simple. Furthermore, such simplicity is helpful when trying toextend calculi to study additional features. For example, we will study a non-trivial extension
to PITS, i.e. subtyping, in the second part of the thesis. Integrating subtyping and some form ofdependent types is a widely acknowledged difficult problem [Aspinall and Compagnoni 1996;
Castagna and Chen 2001; Hutchins 2010]. Nevertheless, in Chapter 5 we will show that using
the call-by-name instance of PITS extension with subtyping, we can develop a calculus that
subsumes System F6 [Cardelli et al. 1994] and has several interesting properties, including subject
reduction and transitivity of subtyping. We believe this development would be a lot harder to do
by extending full PITS or PTSf .

4.4.3

No Mutually Dependent Judgments

PTSf requires more language mechanisms for type conversions, including proof terms (H) andtheir typing rules (Γ `f H : A = B) to ensure coercions (A = B) are well-typed. Moreover, thewell-formedness checking of coercions depends on typing judgments (Γ `f e : A), which causes
mutual dependency of judgments and complicates proofs. Casts in PITS use reduction relations(A ,→ B ), which are untyped and do not depend on typing rules. The well-formedness of types
is checked separately in typing rules of cast operators, e.g. TF-Castup and TF-Castdn in full
PITS. The fact that PITS does not require such mutually dependent judgments means that many
proofs can be proved using simple inductions. In PTSf the mutually dependent judgments leads
to several lemmas that need to be mutually proved.

4.4.4

Implicit Proofs by Reduction

PTSf uses coercions (i.e. equivalence relations) to explicitly write equality proofs, while PITS uses
reduction relations that implicitly construct such proofs. Equality proofs in PTSf are constructedby proof terms. Each language construct requires a corresponding proof term to reason aboutChapter 4. Pure Iso-Type Systems

64

equality of sub-terms, which adds to the number of language constructs. On the contrary, PITS
does not require proof terms but two extra cast operators, thus has fewer language constructs.
Type conversions in PTSf are more “explicit” than in PITS. One needs to specify which
proof terms to be used exactly in PTSf , while he/she just needs casts without specifying which
underlying reduction rule to use. This makes it easier to do explicit type conversions in PITS.
Assume that we have integer literals and use beta reduction to evaluate addition (1 + 1 ,→ 2):e : Πx : Int. Vec (1 + 1)
e0 : Πx : Int. Vec 2
To obtain e0 from e, in PTSf , e0 = eH where H is a proof term such thatH = {Int, [x : Int](Vec β(1 + 1))}
In full PITS, e0 = cast⇓ [Πx : Int. Vec 2] e, which implicitly uses the reduction rules P-Prod,
P-App and P-Red in the cast operator. In call-by-name/value PITS, due to the determinacy of
reduction used in casts, the cast↓ operator even does not require a type annotation. For example,
consider a simpler type conversion (λx : ?. x ) Int ,→ Int from Section 3.1.3:
e : (λx : ?. x ) Int
e0 : Int
where e0 can simply be cast↓ e without any annotation.
Generally speaking we believe that for programming, and especially more traditional forms
of programming that do not involve complex forms of type-level reasoning, having such implicit
proofs of conversion is good. We believe that for a practical language design to be based directly
on PTSf it would require some degree of inference of the equality proof terms. In some sense full
PITS can be thought of a system that implicitly generates proof terms and in principle could betranslated to PTSf , but it is one step closer to a source language that infers equality proof terms.
Of course if the goal is to do theorem proving and/or heavy uses of type level computation thenhaving explicit control over the equality proof terms can be an advantage. However for PITS our
focus is on programming languages with general recursion.

4.4.5

Full Type-Level Computation

PTSf has full type-level computation since type conversion uses equivalence relations which arecongruent. It has the same expressive power as Pure Type Systems. Full PITS similarly has full
type-level computation, while call-by-name/value PITS do not. Full type-level computation isuseful for theorem proving and full-spectrum dependently typed programming as in Coq andAgda, but not necessarily required for traditional programming. As the examples presented in
Section 3.2 show, iso-types that just use weak-head call-by-name reductions in casts can encode
many advanced type-level features. The extra expressiveness of PTSf and full PITS also comes atthe cost of additional complexity in the metatheory and makes it non-trivial to achieve features
like direct dynamic semantics and direct type-safety proofs.

4.4. Discussion

4.4.6

65

Consistency of Reduction

In many strongly normalizing languages a basic assumption is that the order of reduction does notmatter. This justifies reasoning that can be done in any order of reduction. Reduction strategies
such as parallel reduction embody this principle and enable reductions in terms to occur inmultiple orders. However, in languages with general recursion this assumption is broken: i.e.
reduction order does matter. For example, term “(λx : Int. 1) ⊥” loops in call-by-value reduction,
but terminates in call-by-name reduction. If we want to conduct precise reasoning about programsand their behavior we cannot ignore the order of reduction. In particular, if we want the typelevel reduction to respect the run-time semantics/reduction then we need to ensure that the two
reductions are in some sense consistent. To (trivially) ensure consistency call-by-name/value PITS
uses the same reduction relation for both term evaluation and type conversion. In full PITS, theuse of parallel reduction breaks consistency because type-level reduction allows some reductions
that are not allowed by term-level reduction. For example, Int → Vec (1 + 1) can be reduced to
Int → Vec 2 by type-level parallel reduction but not term-level reduction. We believe that it may
be possible to have a variant of PITS that uses call-by-name or call-by-value and has a consistent
form of full reduction that respects the reduction order. However we leave this for future work(see Section 8.2).
PTSf has no discussion on reduction rules for term evaluation, since its dynamic semantics isgiven by elaboration into PTS. Since the focus of PTSf is primarily on the applications to theorem
proving the issues of consistency between term and type-level reduction are not relevant, becausesuch for theorem proving calculi are normally strongly normalizing and reduction order does notaffect the semantics.

4.4.7

Decidability in the Presence of Recursion

There is no formal discussion or a direct proof on decidability of the type system for PTSf , though
this seems to be a plausible property since the typing rules of PTSf are syntax-directed. Only
uniqueness of typing is formally discussed and proved for functional PTSf . This is similar tofunctional PITS which have uniqueness of typing up to only alpha equality due to the absence of
implicit beta conversion (see Lemma 4.1.1). Uniqueness of typing is used in the decidability proofof functional PITS (see Section 4.1.5), and we believe that it should be useful to prove decidabilityof PTSf as well.
Alternatively, note that an indirect proof for decidability of typing can be derived fromthe plain metatheory of PTS through the equivalence of PTSf and PTS. However, the original
decidability proof for PTS relies on the normalization property [van Benthem Jutting 1993]. Thus,
non-normalizing PTSf cannot use such indirect approach to prove decidability for variants of
PTSf with recursion/fixpoints.
For all three variants of PITS, decidability of type checking has been proved directly in thepresence of general recursion without relying on normalization, though the proof is done only
for functional PITS for simplicity reasons. We expect that a similar proof would work for PTSf as
well, and this would be interesting to prove in future work.

67

Part II:
Iso-Types with Subtyping

69

CHAPTER

5

Unifying Typing and Subtyping

In this chapter, we present λI6 , which is a dependently typed generalization of System F6 . The
motivation is to design a simple yet expressive calculus that combines dependent types and
OOP features. Subtyping is one of the key OOP features but the combination of subtyping anddependent types causes mutual dependency of typing and subtyping judgments and circularity inthe metatheory. To address these challenges, λI6 employs a novel technique that unifies typing
and subtyping. In λI6 there is only one judgment that is akin to a typed version of subtyping.
Both the typing relation, as well as type well-formedness are just special cases of the subtyping
relation. Therefore, λI6 takes a significantly different approach compared to previous work.
Previous work essentially attempts to fight the entanglement between typing and subtyping. In
contrast, what we propose with λI6 is to embrace such tangling, and essentially collapsing thetyping and subtyping relations into the same relation. Our approach is also different from thetechnique of Pure Subtype Systems by Hutchins [2010], which simply eliminates types and typing.
λI6 retains types.
The λI6 calculus employs the idea of iso-types in PITS. It follows the PTS-style unified
syntax and contains a single unified syntactic sort that accounts for expressions, types and kinds.
Iso-types provide a simple form of type casts, and λI6 adopts that idea to address the issues
arising from the combination of recursion and dependent types. The novelty over PITS is the
support for OOP features such as higher-order subtyping [Pierce and Steffen 1997], bounded
quantification [Cardelli et al. 1994] and top types. To illustrate the expressive power of λI6 , weshow how object encodings relying on higher-order subtyping can be done in λI6 . The resulting
calculus enjoys several standard and desirable properties, such as subject reduction, transitivity of
subtyping, narrowing as well as standard substitution lemmas. We also provide an algorithmic
version of λI6 based on bi-directional type-checking [Pierce and Turner 2000], which is shown
to be sound and complete with respect to the declarative version. Finally we show that λI6completely subsumes System F6 in expressive power.

5.1

Overview

In this section, we briefly discuss the problem of combining dependent types with subtyping. We
informally introduce the key features of λI6 calculus, namely unified subtyping and the support
for dependent types by explicit casts. To illustrate the suitability of λI6 to model objects, we
adapt the existential object encoding [Bruce et al. 1999; Pierce and Turner 1994] (originally based

Chapter 5. Unifying Typing and Subtyping

70

on System F6ω ) to λI6 . The formal details of λI6 are further discussed in Sections 5.2 and 5.3.

5.1.1

Unified Syntax versus Stratified Syntax

Calculi with high-order subtyping are usually complex. For example, System F6ω [Pierce andSteffen 1997] adds higher-order subtyping and bounded quantification to System Fω and isformalized using stratified syntax. Because of the separation of syntax, the subtyping relation in
System F6ω needs to be defined over multiple syntactic forms of abstraction, i.e., abstraction overterms, types and type operators:
Term abstraction
Type abstraction
Operator abstraction

λx : A. e
λX 6 A. e
λX 6 A. B

This causes duplication and complexity in the metatheory.
It is tempting to adopt the PTS-style unified syntax in System F6ω to simplify the subtyping
relation. Because System Fω (without subtyping) can be modeled with PTS-style unified syntax: it
is a special case of PTSs and covered by Barendregt’s λ-cube [Barendregt 1992] (see Section 2.1.2).
However, there are several difficulties in applying such simplification to a higher-order system withbounded quantification. Recall that there are three different forms of abstraction in System F6ω . It is
hard to unify them because the abstraction can quantify over a variable using two distinct relations,
i.e., typing (x : A) and subtyping (X 6 A). To obtain a uniform representation of abstraction, we
need to unify the typing and subtyping relation in the first place. Moreover, calculi with PTS-styleunified syntax usually allow dependent types, e.g., the calculus of constructions [Coquand andHuet 1988]. Combining dependent types and subtyping has its own problems, as discussed in the
coming subsection.

5.1.2

Challenges in Combining Subtyping with Dependent Types

Mutual Dependency of Typing and Subtyping. Subtyping and dependent types are wellknown features of programming languages. Individually, each of them is well-studied. However,combining them in the same system is usually difficult. A major reason is that allowing dependent types makes the typing and subtyping relations entangled. The subtyping and typing1
judgments become mutually dependent. The typing judgment depends on subtyping because of
the subsumption rule (see also Section 2.4.1):
Γ`e:A

Γ`A6B

Γ`e:B
Subtyping relations are defined over well-formed types, which are checked by the typing judgment
in a dependently typed system. For example, the subtyping rule for the top type (>), a universal
supertype of any well-formed types (i.e. with kind ?), is defined as follows:
Γ`A:?
Γ`A6>
1
Some stratified systems [Aspinall and Compagnoni 1996; Castagna and Chen 2001] also have the kinding judgment,
which is mutually dependent on typing. We uniformly refer to them as typing.

5.1. Overview

71

Circularity in the Metatheory. The mutual dependency causes circularity in the metatheory,
since one cannot study properties of subtyping independently from typing. For example, λP6 [Aspinall and Compagnoni 1996] is an extension of the second-order dependently typed calculus
λP [Barendregt 1992] with subtyping. In λP6 , the substitution lemmas for typing and subtyping
depend on each other and require a more complicated proof by simultaneously induction on four
different judgments, i.e. subtyping, typing, kinding and formation [Aspinall and Compagnoni
1996]:
Γ`A6B
Γ`M :AΓ`A:K
Γ`K

A is a subtype of B in context Γterm M has type A in context Γtype A has kind K in context Γ
K is a kind in context ΓMoreover, λP6 contains the following algorithmic transitivity rule:Γ ` (Γ(α) M1 · · · Mn )β2 6 A
α bound in Γ, A 6≡ α M1 · · · MnΓ ` α M 1 · · · Mn 6 A
The first premise requires to normalize the term Γ(α) M1 · · · Mn using β2 -reduction, a beta
reduction relation on types. Thus, the transitivity proof depends on β2 -strong normalization. Also,
the transitivity property requires types to be well-formed through β2 -conversion, i.e., the subject
reduction of β2 -reduction. As a consequence, the proofs of transitivity, strong normalization andsubject reduction depend on each other.
Problems of Existing Solutions. There are several existing options to deal with the circularity.
One could carefully prove mutually dependent lemmas together by finding a proper decreasing
metric of induction, similar to the proof of substitution lemma in λP6 . But such method is usually
too specific and cannot be generally applied to other systems, e.g., the substitution proof in λP6
does not apply to λΠ& [Castagna and Chen 2001].
Another approach is to break the mutual dependency simply by forbidding typing fromoccurring in the subtyping judgments. The subtyping judgments are defined over pre-terms, terms
that may not be well-formed. Then one could prove results about subtyping before typing. An
obvious limitation is that subtyping rules that must depend on typing are no longer supported, suchas the top type rule shown above. Several systems using this method, such as PTS 6 [Zwanenburg
1999], drop the support of top types because of such limitation.

5.1.3

Our Solution: Unified Subtyping

We propose a new approach to solve the circularity problem, which also simplifies the syntax. The
λI6 calculus features a single relation for both typing and subtyping, namely unified subtyping.
The relation has the form:Γ ` e1 6 e2 : A
It simultaneously contains the subtyping relation, i.e., e1 is a subtype of e2 , and the typing relation,i.e., e1 and e2 have type A. The ordinary typing judgment can be seen as a special case of unified
subtyping:Γ`e:A,Γ`e6e:A

72

Chapter 5. Unifying Typing and Subtyping

We solve the circularity problem because typing and subtyping cannot be mutually dependent
in the first place: they are essentially the same relation. In λI6 , subtyping relations can be definedover well-formed terms. Subtyping rules that depend on typing are allowed without causing
mutual dependencies. As a result, top types are supported in λI6 . Moreover, the metatheory of
λI6 is significantly simplified, e.g., there is only one form of substitution lemma to be proved, as
discussed in Section 5.3.
Bounded quantification in λI6 . λI6 adopts a unified syntax and supports bounded quantification. Because of the unified representation of typing and subtyping, instead of three separate
forms of abstraction in System F6ω , λI6 has a single form of abstraction: λx 6 e1 : A. e2 . By convention, the ordinary unbounded abstraction can be treated as syntactic sugar of a top-boundedone:
λx : A. e , λx 6 > : A. e
Notice that the top type (>) is generalized to have any kind A instead of ?. With unified syntax,
λI6 has fewer language constructs than System F6ω and a simpler definition of (unified) subtyping
relation (see Section 5.2).

5.1.4

Iso-Types: Dependent Types without Strong Normalization

Most traditional dependently typed languages are strongly normalizing (i.e. all programs terminate). Strong normalization plays a fundamental role in the metatheory of those languages.
However, nearly all general-purpose programming languages allow non-terminating programs,
so depending on strong normalization is a non-starter if we want to model traditional generalpurpose languages. The root of the dependency on strong normalization is the conversion rule (seeSection 3.1.1). For dependently typed languages with subtyping, the conversion rule is usuallysubsumed by the subsumption rule (see Section 5.1.2), which requires the subtyping relationΓ ` A 6 B to subsume beta-equivalence A =β B. Thus, the transitivity of subtyping may also
depend on strong normalization if its proof requires to first normalize the types [Aspinall andCompagnoni 1996].
An alternative to the conversion rule. Several existing studies [Stump et al. 2008; Sjöberg
et al. 2012; Kimmell et al. 2012; Sjöberg and Weirich 2015; Yang et al. 2016] provide a way to
combine general recursion with dependent types, while preserving important properties (such as
decidability of type-checking). The key idea is to replace the implicit conversion rule with explicit
type casts. This has the effect that term/type equality becomes weaker: two terms are only equal
up to syntactic equality (not beta-equality). To recover type conversion, an explicit cast must be
used. The benefit of this design is that it decouples several properties from strong-normalization.
λI6 adopts the iso-type approach [Yang et al. 2016] of PITS introduced in Chapters 3 and 4. The
cast operators of λI6 employ the weak-head call-by-name reduction relation (see Section 5.2.2),
similarly to the one used by call-by-name PITS (see Section 4.1). This makes the type conversion
by casts less expressive than what is provided by the implicit conversion rule. Nevertheless, we do
not consider such loss of expressiveness problematic. The absence of conversion rule significantly
simplifies the metatheory of λI6 because typing and subtyping are up to alpha-equality andstrong normalization is not a necessity for proofs. Since our goal is to design a calculus for
traditional programming, we do not require the ability to do full type-level computation that is5.1. Overview

73

required for dependently typed programming. Call-by-name casts are still expressive enoughfor our purposes: to model object encodings. Furthermore, there are alternative designs of casts
using call-by-value or full reduction rules (see Sections 4.2 and 4.3), but they introduce some extra
complications to the metatheory. Alternative approaches are discussed in Section 5.6.

5.1.5

Example: Object Encodings using λI6

We show an example of object encodings in λI6 using the existential encoding method [Pierce
and Turner 1994; Bruce et al. 1999] originally based on System F6ω . The example in this section
has two notable differences from the previous example shown in Section 3.2.3 for PITS. First, theobject encodings in this section do not rely on Scott-encodings of algebraic datatypes. Instead, we
directly encode pairs, records and existential types by Church-encoding weak dependent sums in
λI6 . Second, the example in this section supports generic message passing that requires subtyping,which was missing in Section 3.2.3.
Encoding Existential Types and Pairs using Weak Sums. Existential types and pairs are
special cases of dependent sums. Existential types specialize A to kind ?:∃x. B , Σx : ?. B
The constructor and destructor of an existential package are simply pack and unpack operatorsof dependent sums, respectively. Pairs are non-dependent sums where x is not free in B. The
pair type, constructor and destructors can be encoded as follows:
A×B(e1 , e2 )
fst e
snd e

,
,
,
,

Σx : A. B
where x ∈/ FV(B)
pack [e1 , e2 ] as Σx : A. B where x ∈/ FV(B)
unpack e as [x, y] in x
unpack e as [x, y] in ywhere in the encoding of constructor, A and B are types of e1 and e2 , respectively.
Notice that here we only need the weak destructor of dependent sums [Schmidt 1994], i.e., theunpack operator that requires x and y are not free in the type C of e2 (see Section 2.2.1). We use
the same Church-encodings of weak sums from Section 2.2.1 and show that subtyping and typing
rules of weak sums are admissible in λI6 . The proof is trivial and available in Appendix A.1.
However, it is non-trivial to Church-encode strong dependent sums without restrictions on
unpack and using only Pi-types [Cardelli 1986b]. In Chapter 6, we will discuss how to support
primitive constructs of strong sums with unified subtyping. For examples in this section, weak
dependent sums are sufficient for our purpose to encode existential types and non-dependent pairs
and yet more expressive than those constructs. Note that unpack operator allows unrestricted
projection of existential witnesses:
λe : (Σx : A. B). unpack e as [x, y] in x
No such operation is allowed on existential types in System F or F6 [Amin et al. 2016].
Encoding Objects. Now that pairs and existential types can be encoded in λI6 , we present
the encoding of objects. Note again that records can be encoded with pairs using standardChapter 5. Unifying Typing and Subtyping

74

techniques [Pierce 2002] and that we assume λI6 is extended with integers, pairs, records andexistential types in the following text. We use the same example of cell objects as shown in
Section 3.2.3. We first present the existential encoding of objects [Pierce and Turner 1994] in λI6 :Obj = λI : ? → ?. ∃X. X × (X → I X)
The definition of cell objects [Bruce et al. 1999] is as follows:
Cell = λX : ?. {get : Int, set : Int → X, bump : X}
Similarly, a cell object c can be defined as follows:c = cast↑ [Obj Cell ] pack [{x : Int}, ({x = 0}, λs : {x : Int}. cast↑ [Cell {x : Int}]{get = s.x, set = λn : Int. {x = n},bump = {x = s.x + 1}} )]as CellT
We use the pack operator to create an existential package. The type {x : Int} corresponds
to the existential binder X. The pair afterwards corresponds to the body of the existential type.
The first component of the pair is the initial hidden state {x = 0}. The second component is afunction containing three methods that are defined in a record and abstracted by the state variable
s. The definition of the three methods follows the cell object interface Cell . The result type of
the package, i.e., CellT , is the one-step reduction of Obj Cell :CellT = ∃X. X × (X → Cell X)
As in Section 3.2.3, we also use two cast↑ operators here: one over the pack operator and anotherover the record of methods. Note that the desired type of the object c (i.e. Obj Cell ) is a type-levelapplication, which is different from CellT . We use cast↑ to do one-step type expansion forthe package: Obj Cell ,→ CellT . Similarly, we use another cast↑ operator in the definition of
methods to convert the record type into Cell {x : Int}. We use the following syntactic sugar forconsecutive cast↑ and pack:
pack [A, e] up B , cast↑ [B] (pack [A, e] as B 0 )where B ,→ B 0 , i.e., B 0 is the one-step reduction of B.
In addition to the previous example in Section 3.2.3, we can further define message passing
to the object by the unpack operator to open a package. For example, sending message get tothe cell object c is denoted by c ⇐ get, which is syntactic sugar of the generic message function
getM :c ⇐ get , getM Cell cgetM = λI 6 Cell : ? → ?. λo : Obj I.
unpack (cast↓ o) as [X, (s, m)] in (cast↓ (m s)).get
getM is parameterized by interface I and object o with such interface, where I can be any
sub-interface of Cell . We first use the cast↓ operator to convert the type of o from Obj I to
the existential type ∃X. X × (X → I X). Note that we extend the syntax of unpack with

5.1. Overview

75(c ⇐ bump) ⇐ get= ( (cast↑ [Obj Cell ] pack [{x : Int}, ({x = 0}, f )] as CellT ) ⇐ bump ) ⇐ get= ( unpack (cast↓ (cast↑ [Obj Cell ] pack [{x : Int}, ({x = 0}, f )] as CellT )) as [X, (s, m)] inpack [X, ((cast↓ (m s)).bump, m)] up (Obj Cell ) ) ⇐ get,→ ( unpack (pack [{x : Int}, ({x = 0}, f )] as CellT ) as [X, (s, m)] inpack [X, ((cast↓ (m s)).bump, m)] up (Obj Cell ) ) ⇐ get,→ (pack [{x : Int}, ((cast↓ (f {x = 0})).bump, f )] up (Obj Cell )) ⇐ get= unpack (cast↓ (pack [{x : Int}, ((cast↓ (f {x = 0})).bump, f )] up (Obj Cell )))as [X, (s, m)] in (cast↓ (m s)).get= unpack (cast↓ cast↑ [Obj Cell ] (pack [{x : Int}, ((cast↓ (f {x = 0})).bump, f )] as CellT ))as [X, (s, m)] in (cast↓ (m s)).get,→ unpack (pack [{x : Int}, ((cast↓ (f {x = 0})).bump, f )] as CellT )as [X, (s, m)] in (cast↓ (m s)).get,→ (cast↓ (f ((cast↓ (f {x = 0})).bump))).get,→ (cast↓ (f [(cast↓ (f {x = 0})).bump])).get,→ { get = ((cast↓ (f {x = 0})).bump).x, set = λn : Int. {x = n},bump = {x = ((cast↓ (f {x = 0})).bump).x + 1} }.get,→ ((cast↓ (f {x = 0})).bump).x,→ ((cast↓ f [{x = 0}]).bump).x,→ ({ get = {x = 0}.x, set = λn : Int. {x = n},bump = {x = {x = 0}.x + 1} }.bump).x,→ {x = {x = 0}.x + 1}.x ,→ · · · ,→ 1

Figure 5.1. Evaluation of (c ⇐ bump) ⇐ get
simple pattern matching on pairs for brevity. The hidden state is unpacked as s with type X. The
function containing methods is m with type X → I X. The record of methods can be obtainedby applying m to s. Noting that the subtyping relation I X 6 Cell X holds, the type of m s
can be converted from I X to Cell X by subsumption. Another cast↓ further reduces Cell X torecord type for accessing the member get. The encoding of message bump is similar but needs torepack the resulting object:c ⇐ bump , bumpM Cell cbumpM = λI 6 Cell : ? → ?. λo : Obj I.
unpack (cast↓ o) as [X, (s, m)] inpack [X, ((cast↓ (m s)).bump, m)] up (Obj I)
since the bump method returns a record but not an object. The extra pack here is required tocreate a new object using the result of bump as the new hidden state.
Similarly to the original example [Bruce et al. 1999], we can examine the encoding by evaluating the expression (c ⇐ bump) ⇐ get using call-by-name reduction (,→). In Figure 5.1, weshow the evaluation steps of the expression (c ⇐ bump) ⇐ get using call-by-name reduction(,→). The evaluation result is 1 as expected, where f is the function containing the definition of
methods:
f = λs : {x : Int}. cast↑ [Cell {x : Int}]{get = s.x, set = λn : Int. {x = n}, bump = {x = s.x + 1}}

Chapter 5. Unifying Typing and Subtyping

76
and f [r] is one-step reduction of the application f r:

f [r] = cast↑ [Cell {x : Int}]{get = r.x, set = λn : Int. {x = n}, bump = {x = r.x + 1}}
Note that we assume reduction rules for records, existential packages and integer addition areavailable in the call-by-name reduction relation (,→). We skip steps for desugaring the message
sending operation, e.g., o ⇐ get = getM [Cell ][o]. We emphasize that the object encoding
example here requires the additional feature of λI6 over PITS, i.e., higher-order subtyping, whichis essential for encoding generic message functions.

5.2

The λI6 Calculus

We present the λI6 calculus in this section. The calculus features a unified syntax with only
one syntactic level, and it is based on the λI calculus [Yang et al. 2016], a specific PITS witha single sort ? and the “type-in-type” axiom (see Section 3.2.1). The novelty over λI/PITS is
subtyping. To integrate subtyping, typing is unified with the subtyping relation. Thus the typing
relation can be viewed as a special case of subtyping. We demonstrate the syntax, operationaland static semantics of λI6 in the rest of this section. Notice that λI6 discussed in this section
does not contain recursion, which can be supported by following PITS. We leave the discussionof recursion to Section 5.6.

5.2.1

SyntaxFigure 5.2 shows the syntax of expressions in λI6 . It follows the unified syntax of Pure Type
Systems [Barendregt 1992] where terms, types and a single kind ? are defined in the same syntactic
category. By convention, we still use different metavariables to indicate if expressions are terms(e) or types (A, B, C, etc.).
Cast Operators. As in PITS, cast operators cast↑ and cast↓ are used for explicit type-levelcomputation in λI6 . In particular, cast↓ and cast↑ convert the type of an expression by a one-step
reduction or expansion, respectively. cast↑ needs to be annotated with the result type of one-step
expansion, while cast↓ does not, since one-step reduction is deterministic (see Section 5.3.4).
Bounded Quantification. Functions are written as λx 6 e1 : A. e2 , which support bounded
quantification as in System F6 [Cardelli et al. 1994]. The bound term e1 is annotated with atype A. Correspondingly, function types written as Πx 6 e : A. B also contain a bound terme. Function types can be dependent if x occurs free in B. The top type > is a supertype of any
well-formed term, e.g., 3 6 >. The top type generalizes the conventional top type in System F6 ,which is only a supertype of well-formed types, e.g., Int 6 >.
Syntactic Sugar. Unbounded functions (λx : A. e) and function types (Πx : A. B ) are notdefined as primitives in the syntax. With the generalized top type, we can define them as syntactic
sugar of top-bounded ones, i.e., λx 6 > : A. e and Πx 6 > : A. B as shown in Figure 5.2. We
also treat arrow types A → B as syntactic sugar of Πx : A. B if x does not occur free in B .

5.2. The λI6 Calculus

77

Expressionse, A, B

::=
|
::=
::=
::=

Contexts
Inert Terms
ValuesSyntactic SugarΓuv
λx : A. e
Πx : A. B
A→B

x | ? | > | e1 e2 | cast↑ [A] e | cast↓ e
λx 6 e1 : A. e2 | Πx 6 e : A. B
∅ | Γ, x 6 e : A
x | > | u e | cast↓ u? | λx 6 e1 : A. e2 | Πx 6 e : A. B | cast↑ [A] e | u, λx 6 > : A. e
, Πx 6 > : A. B
, Πx : A. B
where x 6∈ FV(B )Figure 5.2. Syntax
Context. The syntax of context Γ is defined in Figure 5.2. The variable binding only has thebounded form x 6 e : A where the bound term e has type A. Similar to the treatment of
unbounded functions above, we can treat an unbounded variable binding as the syntactic sugarof a top-bounded binding, i.e., Γ, x : A , Γ, x 6 > : A.

5.2.2

Operational Semantics

Figure 5.3 shows the definition of one-step reduction (,→), which is used for both evaluation andtype conversion (via cast operators). It follows the call-by-name style and is weak-head. R-Beta
performs the beta reduction and does not require the argument to be a value. R-CastElim cancels
consecutive cast↓ and cast↑ . R-App and R-CastDn perform reduction at the head term of an
application and the inner term of cast↓ , respectively.
Since the reduction relation (,→) is also used for type conversion, we may encounter open
terms during reduction. However, some open terms are stuck terms that are not reducible by,→. For example, an application starting with a variable: x e1 e2 . . . en . Also, as the top type isgeneralized, assuming it is a supertype of an n-ary function, we can have a well-formed but stuck
term such as > e1 e2 . . . en . Furthermore, if we replace x and > in both stuck terms by cast↓ x
and cast↓ > respectively, they still cannot be reduced.
We introduce a syntactic category called inert terms to cover such stuck terms. The terminology
is inspired by the fireball calculus [Paolini and Della Rocca 1999; Accattoli and Guerrieri 2016].
Figure 5.2 shows the definition of inert terms, ranged over by metavariable u. Two base inert
terms are variables and the top type. Compound inert terms are either an application leadingwith an inert term, i.e., u e, or down-cast inert term, i.e., cast↓ u. We treat inert terms as values.
Figure 5.2 shows the syntax of values, ranged over by metavariable v, as shown in Figure 5.2. A
value can either be the kind ?, a function, a function type, a cast↑ term or an inert term.
There are several alternative designs on reduction rules and syntax of values, e.g., beta-top(β>) reduction [Pierce and Steffen 1997] and cast↑ [A] v as a value [Pierce 2002; Yang et al. 2016].
We will discuss these designs and their trade-offs later in Section 5.6.

5.2.3

Static Semantics

Figure 5.4 shows the rules of static semantics, including two judgment forms: context wellformedness ` Γ and unified subtyping Γ ` e1 6 e2 : A. The unified subtyping judgmentΓ ` e1 6 e2 : A serves as both subtyping and typing judgment. It can be interpreted as “e1 is asubtype of e2 and both of them have type A”. The inference rules are developed to satisfy suchinterpretation. For brevity, if e1 and e2 are the same (i.e. e1 = e2 = e), we use the syntacticChapter 5. Unifying Typing and Subtyping

78(Call-by-name Reduction)

e1 ,→ e2
R-App
R-Beta(λx : A. e1 ) e2 ,→ e1 [x 7→ e2 ]e1 ,→ e10e1 e2 ,→ e10 e2

R-Muµx : A. e ,→ e[x 7→ µx : A. e]

R-Castdn

e ,→ e 0
cast↓ e ,→ cast↓ e 0

R-CastElim

cast↓ (cast↑ [A] e) ,→ e

Figure 5.3. Operational semantics
sugar Γ ` e : A (see Figure 5.4), which also has the same form of typing judgment in traditional
systems. We also use Γ ` A : ? to check if type A is well-formed, i.e., has the kind ?. Thus in λI6 ,subtyping, typing and well-formedness of types are all unified by the unified subtyping judgment:
Unified SubtypingΓ ` e1 6 e2 : A
TypingΓ`e:A , Γ`e6e:A
Well-formed Types Γ ` A : ? , Γ ` A 6 A : ?

A key benefit of unified subtyping is that the mutual dependency issue between typing andsubtyping found in many traditional higher-order subtyping systems can be avoided since typing
is just a special case of subtyping.
The context well-formedness judgment ` Γ is defined inductively on the structure of Γ.
Whenever adding a fresh binding x 6 e : A to the context Γ, the judgment ensures e has awell-formed type A.
We briefly introduce the basic rules and discuss the rest in detail. S-Ax defines the reflexivityof the kind ? and follows the “type-in-type” axiom [Cardelli 1986b] for the typing of ?. S-VarRefldefines the reflexivity of a variable and its typing by looking up the context. S-VarTrans defines
the variable lookup followed by transitivity, which follows the algorithmic version of System
F6 [Curien and Ghelli 1992].
Generalized Top Type. S-Top defines subtyping for the generalized top type: a supertype ofany term e which has the same type A as e. A special case is when e is also a top type. For thiscase we need to define the reflexivity of top type as in the rule S-TopRefl, which indicates thatthe top type can have any well-formed type A. In other words, any well-formed type can beinhabited by the generalized top type, which causes logical inconsistency. Note that allowing“type-in-type” axiom in S-Ax already brings logical inconsistency [Barendregt 1992]. Our goal is
to investigate the calculus for traditional programming that allows general recursion, which is
logically inconsistent any way. Thus, we do not consider generalized top type or “type-in-type”
axiom problematic. With top type generalized, bounded and unbounded quantification are unified,
which significantly simplifies the system.
Functions and Function Types. S-Abs defines the subtyping relation between functions,which follows the invariant rule for type operators in System F6ω [Pierce and Steffen 1997]. It
requires the bounds and argument types being compared to be identical. The first line of premises
in S-Abs checks the well-formedness of binding. The second line of premises checks if the function
bodies are covariant and their type is well-formed.

5.2. The λI6 Calculus`Γ79
WU-Cons

Context Well-formedness

Γ`e:A
Γ`A:?
` Γ, x 6 e : A

WU-Empty`∅Γ ` e1 6 e2 : A(Unified Subtyping)

S-Ax

S-VarRefl

S-VarTrans`ΓΓ`?6?:?

`Γx 6 e1 : A ∈ ΓΓ ` e1 6 e2 : AΓ ` x 6 e2 : A

x 6e:A ∈ ΓΓ`x 6x :A
S-Abs

Γ ` e1 : A
Γ, x 6 e1 : A ` e2 6 e20 : B
Γ, x 6 e1 : A ` B : ?
Γ ` (λx 6 e1 : A. e2 ) 6 (λx 6 e1 : A. e20 ) : Πx 6 e1 : A. B
Γ`A:?

S-Top

S-TopReflΓ`e:AΓ`e6>:AΓ`A:?
Γ`>6>:AS-App

Γ ` e1 6 e2 : Πx 6 e3 : B . CΓ ` A 6 e3 : BΓ ` e1 A 6 e2 A : C [x 7→ A]
S-ProdΓ ` A0 6 A : ?
Γ`e:A
Γ`A:?
Γ, x 6 e : A ` B : ?
Γ, x 6 e : A0 ` B 6 B 0 : ?
Γ ` (Πx 6 e : A. B ) 6 (Πx 6 e : A0 . B 0 ) : ?
0

S-CastUpΓ`B :?
Γ ` e1 6 e2 : A
B ,→ AΓ ` cast↑ [B ] e1 6 cast↑ [B ] e2 : B

S-CastDn

S-SubΓ`B :?
Γ ` e1 6 e2 : A
A ,→ BΓ ` cast↓ e1 6 cast↓ e2 : BΓ ` e1 6 e2 : A
Γ`A6B :?
Γ ` e1 6 e2 : B

Syntactic Sugar

Γ`e:A,Γ`e6e:A
Figure 5.4. Static semantics

S-Prod defines the relation between function types. Unlike S-Abs, it only requires the bounds
to be identical. The argument types can vary and are contravariant. Such design follows the Kernel
Fun variant [Cardelli and Wegner 1985] of System F6 . S-Prod can be viewed as a combination of
the subtyping rules for arrow types and universal types of System F6 :FS-Arrow∆ ` T1 6 U1

FS-Forall∆ ` U2 6 T2

∆ ` (U1 → U2 ) 6 (T1 → T2 )∆, X 6 U ` T1 6 T2
∆ ` (∀X 6 U . T1 ) 6 (∀X 6 U . T2 )The first premise of S-Prod checks the contravariance of argument types, similar to the rule forarrow types. The last premise checks the covariance of co-domains of function types with boundfixed, similar to the rule for universal types. Other premises check the well-formedness.
Pointwise Subtyping. S-App defines subtyping between applications and uses a pointwise
subtyping rule originated from System F6ω [Pierce and Steffen 1997], which is also used in manysystems with higher order subtyping [Hutchins 2010; Aspinall and Compagnoni 1996; Zwanenburg
1999]. When comparing two applications, we require the arguments to be identical and only
compare the head terms, equivalently to type operators in F6ω . The first premise of S-App ensures
the head term to have a function type, e.g., Πx 6 e3 : B . C . The second premise checks thebound and typing requirements: if the argument A is a subtype of e3 and A has the type B.

Chapter 5. Unifying Typing and Subtyping

80

Explicit Casts and Syntactic Equality. S-CastUp and S-CastDn are rules for explicit castoperators. They can be seen as a generalization of typing rules of fold and unfold from isorecursive types (see Section 4.1.4). Weak-head reduction (,→) is used for type-level conversion.
Note that when comparing cast↑ terms, we require the annotations to be the same. S-Sub isthe subsumption rule. The second premise checks the subtyping relation between well-formed
types by reusing the unified subtyping judgment. Note that S-Sub does not subsume the implicit
conversion rule, which can be found in F6ω and Pure Type Systems. Because the unified subtyping
judgment does not subsume beta conversion, i.e., (λx : ?. x ) Int 6 Int does not hold. As aconsequence, types of expressions are equal only up to syntactic equality (i.e. alpha equality),
but not beta equality. Nevertheless, we can recover type-level computation through explicit castoperators.
Algorithmic up to Subtyping. The unified subtyping rules shown in Figure 5.4 are declarative
because of the subsumption rule S-Sub. But the system is almost algorithmic: if we ignore thetyping result and only consider the subtyping part, the system becomes algorithmic. Like thealgorithmic version of System F6 , there is no built-in transitivity rule defined in λI6 . Actually,transitivity can be proved from other rules (see Section 5.3.2).

5.3

The Metatheory of Unified Subtyping

In this section, we discuss the metatheory of λI6 by focusing on two main targets: transitivity
and type safety. We emphasize here that in previous work the metatheory for the combination
between dependent types and subtyping was a key difficulty, greatly due to the entanglement
between the metatheory of subtyping and typing. With unified subtyping we develop a single
metatheory for the new relation instead. Traditional theorems related to the metatheory of typing
and subtyping can then be viewed as particular instantiations of the unified subtyping theorems.
Because the unified subtyping relation is new, working out the metatheory for our system actuallyrequired figuring out which theorems to prove (i.e. what form should they have); and in which
order to prove them. It is crucial (and non-trivial) to prove the right theorems in the correct
order. Nevertheless, once the form of the theorems and the order in which they should be proved
are set, then the proofs can actually be done with simple techniques similar to those used in
more traditional systems. The dependency diagram of main lemmas in this section is shown in
Figure 5.5.

5.3.1

Basic Lemmas

Before going to the proof of transitivity, we first discuss several important basic lemmas includingreflexivity, weakening, consistency of typing and narrowing.
Reflexivity. The subtyping relation in System F6 is reflexive, i.e., ∆ ` T 6 T holds for any
well-formed type T and context ∆. Since unified subtyping in λI6 tracks typing results, therelation in reflexive form, i.e., Γ ` e 6 e : A, works like a typing judgment Γ ` e : A (recall thesyntactic sugar in Figure 5.4). Reflexivity does not hold for arbitrary e and A. However reflexivity
does hold for any well-(sub)typed terms. That is:
Lemma 5.3.1 (Reflexivity). If Γ ` e1 6 e2 : A, then both Γ ` e1 : A and Γ ` e2 : A hold.

5.3. The Metatheory of Unified Subtyping

81

Type Preservation (5.3.13)

Right Reflexivity (5.3.3)

Generalized Subtype Preservation (5.3.15)

Correctness of Types (5.3.11)

Bound Narrowing (5.3.7)

Substitution (5.3.10)

Transitivity (5.3.9)
Type Narrowing (5.3.6)
Weakening (5.3.4)

Consistency of Typing (5.3.5)

Left Reflexivity (5.3.2)

Figure 5.5. Dependency of lemmas for the metatheory of unified subtyping

This lemma is also called validity in some literature [Abel and Rodriguez 2008]. Here we callit “reflexivity” because conclusions are still (unified) subtyping relations in reflexive form. It
also meets the interpretation of unified subtyping mentioned in Section 5.2.3. We separate thereflexivity lemma into two sub-lemmas by dividing the conclusion:
Lemma 5.3.2 (Left Reflexivity). If Γ ` e1 6 e2 : A, then Γ ` e1 : A holds.
Lemma 5.3.3 (Right Reflexivity). If Γ ` e1 6 e2 : A, then Γ ` e2 : A holds.
Left reflexivity can be proved by induction on the derivation of Γ ` e1 6 e2 : A. However, rightreflexivity is difficult to prove due to the generalized top type. Consider the case of S-Top, i.e.,Γ ` e 6 > : A. We know Γ ` e : A from the premise. The target Γ ` > : A requires A to bewell-formed, i.e., Γ ` A : ?, as indicated by the premise of S-TopRefl. To prove Γ ` A : ? fromΓ ` e : A, we need a lemma called correctness of types (Lemma 5.3.11), which is not available
currently. We will show the full proof later in Section 5.3.3. Currently without right reflexivity,
we add redundant premises in typing rules to simplify the proofs. For example, in rule S-Prod,the third premise Γ ` A : ? is derivable from the first premise Γ ` A0 6 A : ? by right reflexivity.
Once right reflexivity is shown, such additional premises can be removed without changing thetype system.
Weakening. The weakening lemma is standard:
Lemma 5.3.4 (Weakening). If Γ1 , Γ3 ` e1 6 e2 : A and ` Γ1 , Γ2 , Γ3 , then Γ1 , Γ2 , Γ3 ` e1 6 e2 :A.
The proof is by induction on the derivation of Γ1 , Γ3 ` e1 6 e2 : A. The only interesting caseis when S-Prod is the last derivation. The last premise of S-Prod adds binding x 6 e : A0 into
the context Γ. We need to ensure A0 is well-formed, i.e., Γ ` A0 : ?, as required by context
well-formedness. Though not included in the premise, it can be derived by applying left reflexivity(Lemma 5.3.2) to the first premise, i.e., Γ ` A0 6 A : ?.
Consistency of Typing. We prove a simple yet important lemma, called consistency of typing:Chapter 5. Unifying Typing and Subtyping

82

Lemma 5.3.5 (Consistency of Typing). If Γ ` e1 : A and Γ ` e1 6 e2 : B , then Γ ` e1 6 e2 : A.
The proof is by induction on the derivation of Γ ` e1 6 e2 : B . This lemma is the key todecoupling typing from unified subtyping. To prove Γ ` e1 6 e2 : A, we can individually show1) e1 has the type A and 2) e1 is a subtype of e2 regardless of typing, as long as there is some typeB such that Γ ` e1 6 e2 : B .
Narrowing.

We have two narrowing lemmas in λI6 , type narrowing and bound narrowing:

Lemma 5.3.6 (Type Narrowing). Given Γ1 , x 6 e : B , Γ2 ` e1 6 e2 : C , if Γ1 ` A 6 B : ? andΓ1 ` e : A, then Γ1 , x 6 e : A, Γ2 ` e1 6 e2 : C .
Lemma 5.3.7 (Bound Narrowing). If Γ1 , x 6 e : B , Γ2 ` e1 6 e2 : C and Γ1 ` e 0 6 e : B , then
Γ1 , x 6 e 0 : B , Γ2 ` e1 6 e2 : C .
As indicated by the name, for a binding x 6 e : B in the context, type narrowing changes its typefrom B to a subtype A, while bound narrowing changes its bound from e to a subtype e0 . We only
prove type narrowing here, since bound narrowing depends on transitivity, as will be discussed
later in Section 5.3.3. The type narrowing lemma is proved by induction on the derivation ofΓ1 , x 6 e : B , Γ2 ` e1 6 e2 : C . The only interesting case is when the last derivation uses
S-VarTrans, i.e., e1 is a variable. It is easy to prove by the induction hypothesis when e1 is not x.
When e1 = x, we know B = C and our target is to show Γ1 , x 6 e : A, Γ2 ` x 6 e2 : B . By
applying the subsumption rule S-Sub and S-VarTrans, our target becomes Γ1 , x 6 e : A, Γ2 `e 6 e2 : A. Note that we have Γ1 , x 6 e : A, Γ2 ` e 6 e2 : B by the induction hypothesis. The
only gap is the typing result, which should be A but not B. Thus, we can apply the consistencyof typing lemma (Lemma 5.3.5) and prove Γ1 , x 6 e : A, Γ2 ` e : A instead, which is immediate
by weakening (Lemma 5.3.4).

5.3.2

Transitivity

Transitivity is a desirable property of systems with subtyping. Declarative presentations of calculi
often include a built-in transitivity rule:Γ ` e1 6 e2 : AΓ ` e2 6 e3 : A

S-TransΓ ` e1 6 e3 : A

This simplifies the proof of lemmas such as narrowing and substitution. However, noticing that e1
and e3 can be in any form, the rule can be applied any time during derivation, which complicatesthe inversion of subtyping judgments. A process called transitivity elimination [Pierce 2002;
Pierce and Steffen 1997; Compagnoni 1995] can be used to avoid such complexity brought by
the transitivity rule. The declarative system is reformulated into an algorithmic one without atransitivity rule. The transitivity property is then proved against the algorithmic system. Similarly,
we formulate λI6 without a built-in transitivity rule but only with a base case for variables (i.e.
S-VarTrans), as mentioned in Section 5.2.3. Next we show the proof of transitivity in λI6 .
First, we need to generalize the form of transitivity. The form of rule S-Trans is too restricted:
conditions are required to have the same type. This causes issues when both conditions are5.3. The Metatheory of Unified Subtyping

83

derived from S-Sub:
S-Sub
Γ ` e1 6 e2 : B1

Γ ` B1 6 A : ?

S-SubΓ ` e2 6 e3 : B2

Γ ` e1 6 e2 : AΓ ` B2 6 A : ?

Γ ` e2 6 e3 : A

S-TransΓ ` e1 6 e3 : A

We only know B1 and B2 are both subtypes of A but cannot determine the relation between them.
The induction hypothesis cannot be applied since it requires B1 and B2 to be the same. Thus, we
generalize the property intoΓ ` e1 6 e2 : AΓ ` e2 6 e3 : B

S-Trans2Γ ` e1 6 e3 : A

where the conditions are allowed to have different types and the conclusion needs to have thesame type as the first condition. The proof of the generalized transitivity is standard [Pierce 2002]
by induction on the size of e2 and an inner induction on the derivation of the first conditionΓ ` e1 6 e2 : A. We only discuss the interesting case when both derivations end with S-Prod.
We have e1 = Πx 6 e : A1 . B1 , e2 = Πx 6 e : A2 . B2 , and e3 = Πx 6 e : A3 . B3 , withΓ ` A2 6 A1 : ? (1) Γ, x 6 e : A2 ` B1 6 B2 : ? (2)Γ ` A3 6 A2 : ? (3) Γ, x 6 e : A3 ` B2 6 B3 : ? (4)For clarity, we omit all derivations for well-formedness checking in the discussion, which canbe trivially proved by the induction hypothesis. Our target is to prove Γ ` A3 6 A1 : ? andΓ, x 6 e : A3 ` B1 6 B3 : ?. The first target can be obtained by combining (1) and (3) using theouter induction hypothesis since A2 has smaller size than e2 . Noting that the context of the (2) isdifferent from (4) and the second target, we use Lemma 5.3.6 to narrow the type of the binding
to obtain Γ, x 6 e : A3 ` B1 6 B2 : ?. Then we can similarly obtain the second target by theouter induction hypothesis since the size of B2 is smaller than e2 . We conclude the generalized
transitivity by the following lemma:
Lemma 5.3.8 (Generalized Transitivity). If Γ ` e1 6 e2 : A and Γ ` e2 6 e3 : B , thenΓ ` e1 6 e3 : A.
Thus, the original transitivity is an immediate corollary:
Lemma 5.3.9 (Transitivity). If Γ ` e1 6 e2 : A and Γ ` e2 6 e3 : A, then Γ ` e1 6 e3 : A.
As shown in Figure 5.5, the proof of generalized transitivity depends on type narrowing (Lemma
5.3.6) and type narrowing depends on consistency of typing (Lemma 5.3.5). Actually, we can view
consistency of typing as a special case of generalized transitivity by letting e1 = e2 = e01 ande3 = e02 . This indicates that type narrowing can also be proved using generalized transitivity. Thus,an alternative approach is to prove generalized transitivity and type narrowing simultaneously. A
potential issue is that this approach makes these two lemmas mutually dependent. We choose
to first prove a weaker version of generalized transitivity, i.e., consistency of typing, which has
a much simpler proof. Then we can show type narrowing before transitivity without causing
circularity.

Chapter 5. Unifying Typing and Subtyping

84

5.3.3

Basic Lemmas, Revisited

Recall that in Section 5.3.1 we leave two lemmas unproved, i.e., right reflexivity (Lemma 5.3.3)
and bound narrowing (Lemma 5.3.7), which depend on other lemmas that were not available yet.
As we have proved transitivity in Section 5.3.2, we can recover the proof of these two lemmas.
Bound Narrowing. Similar to type narrowing (Lemma 5.3.6), bound narrowing (Lemma 5.3.7)
is proved by induction on the derivation of Γ1 , x 6 e : B , Γ2 ` e1 6 e2 : C . We consider theinteresting case when the derivation ends with S-VarTrans. If e1 is not x, it is trivial to proveby the induction hypothesis. If e1 = x, we have B = C and our target is to show Γ1 , x 6 e 0 :B , Γ2 ` x 6 e2 : B . By the induction hypothesis, we have Γ1 , x 6 e 0 : B , Γ2 ` e 6 e2 : B .
Noticing that by weakening (Lemma 5.3.4), we can obtain Γ1 , x 6 e 0 : B , Γ2 ` e 0 6 e : B fromthe second condition. By transitivity (Lemma 5.3.9), we have Γ1 , x 6 e 0 : B , Γ2 ` e 0 6 e2 : B .
Also noticing that x 6 e 0 : B ∈ Γ1 , x 6 e 0 : B , Γ2 , we obtain the target by the rule S-VarTrans.
Substitution. We show that the substitution lemma holds in λI6 :Lemma 5.3.10 (Substitution). If Γ1 , x 6 e : B , Γ2 ` e1 6 e2 : A and Γ1 ` e 0 6 e : B , then
Γ1 , Γ2 [x 7→ e 0 ] ` e1 [x 7→ e 0 ] 6 e2 [x 7→ e 0 ] : A[x 7→ e 0 ].
The proof is standard by induction on the derivation of the first condition. It is similar to the proofof bound narrowing. Transitivity and weakening are also required for the case when S-TransVar
is the last derivation. Note that the second condition Γ1 ` e 0 6 e : B contains both subtyping
requirement (e0 is a subtype of e) and typing requirement (e0 has type B). Thus, the substitution
lemma in λI6 has only one form.
Right Reflexivity. As mentioned in Section 5.3.1, right reflexivity (Lemma 5.3.3) depends oncorrectness of types:
Lemma 5.3.11 (Correctness of Types). If Γ ` e1 6 e2 : A, then Γ ` A : ?.
But correctness of types also depends on right reflexivity. Consider the last derivation of Γ `e1 6 e2 : A is S-Sub, where the premises are Γ ` e1 6 e2 : B and Γ ` B 6 A : ?. The conclusionΓ ` A : ? holds if we apply right reflexivity to the second premise. Thus, we prove these twolemmas simultaneously by induction on the derivation of Γ ` e1 6 e2 : A. Note that the proof ofcorrectness of types also depends on the substitution lemma (Lemma 5.3.10) when the derivationends with S-App.
With both left and right reflexivity proved, we conclude the reflexivity (Lemma 5.3.1) holds
and the interpretation of unified subtyping in Section 5.2.3 is correct. One key insight here is that
we do not prove the full reflexivity lemma first. Otherwise, it will cause circular dependency inthe metatheory (imagine merging two nodes of left and right reflexivity in Figure 5.5).

5.3.4Type Safety

We prove type safety by showing type preservation and progress lemmas [Wright and Felleisen
1994]. Though both lemmas have the same form as traditional systems, the typing judgment isjust syntactic sugar of unified subtyping, as mentioned in Section 5.2.3.

5.3. The Metatheory of Unified Subtyping

85

Determinacy of Reduction. We first show that the one-step reduction relation is deterministic:
Lemma 5.3.12 (Determinacy of Reduction). If e ,→ e1 and e ,→ e2 , then e1 = e2 .
The proof is straightforward by induction on the derivation of e ,→ e1 . Note that the equality usedin the conclusion is syntactic equality. The result of type-level reduction in the rule S-CastDn(i.e. type B) is unique. Thus, the cast↓ term is not required to be annotated with the result type.
Type Preservation. Type preservation, also known as subject reduction [Wright and Felleisen
1994], states that reducing a term does not change its type:Lemma 5.3.13 (Type Preservation). If Γ ` e : A and e ,→ e 0 , then Γ ` e 0 : A.
However, if we try to directly prove this lemma by induction on the derivation of Γ ` e 6 e : A(i.e. Γ ` e : A), the proof will get stuck. Consider the last derivation is S-CastDn and e ,→ e 0 is
an instance of R-CastElim with e = cast↓ (cast↑ [B 0 ] e) and e0 = e. We have Γ ` cast↑ [B 0 ] e : B
and B ,→ A. By inversion of S-CastUp, we can obtain Γ ` e : A0 , B 0 ,→ A0 and Γ ` B 0 6 B : ?.
Our target is to show Γ ` e : A. If we can prove Γ ` A0 6 A : ?, then the target can be obtained
immediately by the subsumption rule S-Sub. The relation is shown as follows:
B0

6

B

A0

6

A

The subtyping relation in the second line requires a proof, which can be shown by the following
lemma with a more general typing result other than the kind ?:Lemma 5.3.14 (Subtype Preservation). If Γ ` e1 6 e2 : A, e1 ,→ e10 , e2 ,→ e20 , then Γ ` e10 6
e20 : A.
We call this lemma subtype preservation indicating that the unified subtyping relation is preservedby reduction. Type preservation is just a special case of it when e1 = e2 = e and e10 = e20 =e0 . A naïve proof is by induction on the derivation of Γ ` e1 6 e2 : A. The substitution
lemma (Lemma 5.3.10) is required for the case when the derivation ends with S-App and both
reductions are instances of R-Beta. However, the proof gets stuck when the derivation ends with
S-CastDn, and both reductions are instances of R-CastElim with e1 = cast↓ (cast↑ [B ] e10 ) ande2 = cast↓ (cast↑ [B ] e20 ). The induction hypothesis does not work as it requires cast↑ [B ] e10 andcast↑ [B ] e20 to be reducible, while both of them are values (see Figure 5.2). To solve this issue, weneed to generalize the subtype preservation lemma into the following one:
Lemma 5.3.15 (Generalized Subtype Preservation). Given that Γ ` e1 6 e2 : A holds,
1. if both e1 and e2 are cast↑ terms, i.e., e1 = cast↑ [B ] e10 and e2 = cast↑ [B ] e20 , and A ,→ A0 ,B ,→ B 0 , then Γ ` e10 6 e20 : A0 ;2. otherwise, if e1 ,→ e10 and e2 ,→ e20 , then Γ ` e10 6 e20 : A.
Now the proof by induction can proceed with the generalized lemma. For the case which wasstuck in the previous attempt, the conclusion is exactly the induction hypothesis that follows thecase (1) of the lemma. The non-trivial case is when the derivation ends with the subsumption rule

Chapter 5. Unifying Typing and Subtyping

86

S-Sub. When e1 and e2 are not both cast↑ terms, the proof is trivial by the induction hypothesis.
Otherwise, we have e1 = cast↑ [C ] e10 and e2 = cast↑ [C ] e20 such thatΓ ` cast↑ [C ] e10 6 cast↑ [C ] e20 : B
A ,→ A0(1) Γ ` B 6 A : ? (2)(3) C ,→ C 0(4)

Our target is to show Γ ` e10 6 e20 : A0 . Note that the annotations of cast↑ in both terms must be
the same (i.e. C) by S-CastUp. By inversion of (1), we have Γ ` C 6 B : ?. We first show there
exists some B 0 such that B ,→ B 0 by proving the following lemma:
Lemma 5.3.16 (Reduction Exists in the Middle). Given that Γ ` C 6 B : D and Γ ` B 6 A : D,
if C ,→ C 0 and A ,→ A0 , then there exists B 0 such that B ,→ B 0 .
Then by induction hypothesis, we have Γ ` e10 6 e20 : B 0 from (1) by the first case of lemma andΓ ` B 0 6 A0 : ? from (2) by the second (1st case impossible). Thus, we can prove the target by SSub and conclude Lemma 5.3.15. Finally, it is trivial to show that the original subtype preservation
lemma is a corollary of the generalized one. Thus, we can conclude the type preservation lemma
which is an immediate corollary of subtype preservation.
Progress. Progress states that well-formed terms do not get stuck:
Lemma 5.3.17 (Progress). If ∅ ` e : A then either e is a value v or there exists e 0 such thate ,→ e 0 .
As we mentioned in Section 5.2.2, the type-level reduction in cast operators may encounter open
terms. We prove a stronger progress lemma with a non-empty context:
Lemma 5.3.18 (Generalized Progress). If Γ ` e : A then either e is a value v or there exists e 0
such that e ,→ e 0 .
Then the original progress lemma is an immediate corollary of the stronger version. The proof isstraightforward by induction on the derivation of Γ ` e : A. The definition of values is critical tothe proof as it covers many stuck terms with variables and the top type (see also the discussion ofinert terms in Section 5.2.2).

5.4

Algorithmic Version

As we mentioned in Section 5.2.3, the unified subtyping judgment presented in Figure 5.4 isdeclarative but almost algorithmic. The typing part is declarative because of the subsumption
rule, while the subtyping part is algorithmic. If we separately check the typing part and subtyping
part, we just need to develop an algorithm for type checking. We use bidirectional type checking [Pierce and Turner 2000], a standard technique to develop the type checking algorithm for
type systems with subtyping. We show the soundness and completeness of the type and subtype
checking algorithm with respect to the original unified subtyping judgment. Developing a unified
algorithmic system is left as future work, as will be discussed in Section 8.2.

5.4. Algorithmic Version|e|

87

Erasure of Annotations|x | = x|?| = ?
|>| = >
|e1 e2 | = |e1 | |e2 ||λx 6 e1 : A. e2 | = λx 6 |e1 | : |A| . |e2 ||Πx 6 e : A. B | = Πx 6 |e| : |A| . |B ||cast↑ [A] e| = cast↑ [|A|] |e||cast↓ e| = cast↓ |e||(e : A)| = |e||Γ|Erasure of Annotations in Contexts|∅| = ∅
|Γ, x 6 e : A| = |Γ| , x 6 |e| : |A|

Figure 5.6. Erasure of annotations
Γ ` e1 6 e2(Algorithmic Subtyping)

AS-StarΓ`?6?

AS-VarRefl

AS-VarTransx 6e:A ∈ ΓΓ`x 6xx 6 e1 : A ∈ ΓΓ ` e1 6 e2
Γ ` x 6 e2

AS-TopΓ`e6>

AS-AppAS-AbsΓ ` e1 6 e2
Γ ` e1 A 6 e2 A

Γ, x 6 |e3 | : |A| ` e1 6 e2Γ ` (λx 6 e3 : A. e1 ) 6 (λx 6 e3 : A. e2 )AS-Prod

AS-CastUpΓ`C 6AΓ, x 6 |e| : |C | ` B 6 D
Γ ` (Πx 6 e : A. B ) 6 (Πx 6 e : C . D)Γ ` e1 6 e2
Γ ` cast↑ [A] e1 6 cast↑ [A] e2

AS-CastDnΓ ` e1 6 e2
Γ ` cast↓ e1 6 cast↓ e2

Figure 5.7. Algorithmic subtyping

5.4.1

Bidirectional Type Checking

We extend the syntax of λI6 with annotations, denoted by (e : A) (parentheses are required). We
use |e| to denote the erasure of all annotation from a term and |Γ| for the erasure of a context(see Figure 5.6). The algorithmic subtyping judgment is denoted by Γ ` e1 6 e2 in Figure 5.7. It
is developed by removing the typing part of unified subtyping rules in Figure 5.4.
The algorithmic typing judgment has two directions: the checking judgment Γ ` e ⇐ A andthe synthesis judgment Γ ` e ⇒ A, as shown in Figure 5.8. For brevity, we omit the context
well-formedness in all algorithmic typing judgments. Typing rules are developed by following
the typing part of unified subtyping. Most syntactic forms are typed by the synthesis judgment,
including functions and function types since both binders are annotated. Two syntactic forms
that are not annotated require the checking judgment, namely the top type (>) and cast↓ term.
The subsumption rule from the unified subtyping is adapted to the checking direction.

Chapter 5. Unifying Typing and Subtyping

88
Γ`e⇒A

(Synthesis)
AT-AbsΓ ` e1 ⇐ |A|Γ`A⇐?
Γ, x 6 |e1 | : |A| ` e2 ⇒ B
Γ ` λx 6 e1 : A. e2 ⇒ Πx 6 |e1 | : |A| . B

AT-Var
AT-Ax

Γ`?⇒?

x 6e:A ∈ ΓΓ`x ⇒AAT-AppAT-ProdΓ ` e ⇒ Πx 6 e3 : B . CΓ`A⇐BΓ ` |A| 6 e3
Γ ` e A ⇒ C [x 7→ |A|]Γ ` e ⇐ |A|Γ`A⇐?
Γ, x 6 |e| : |A| ` B ⇐ ?
Γ ` Πx 6 e : A. B ⇒ ?

AT-CastUp

AT-AnnoΓ`B ⇐?
Γ`e⇒A|B | ,→ |A|Γ ` cast↑ [B ] e ⇒ |B |

Γ`e⇐A
Γ`A⇐?
Γ ` (e : A) ⇒ |A|Γ`e⇐A(Checking)
AT-TopAT-CastDn

Γ`A⇐?
Γ`>⇐A

Γ`B ⇐?

Γ`e⇒AΓ ` cast↓ e ⇐ B

AT-SubΓ`e⇒A|A| ,→ |B |AT-ChkΓ ` A 6 |B |Γ`e⇐BΓ`B ⇐?

Γ`e⇒A
Γ`e⇐A

Figure 5.8. Bidirectional typing

We use erasure in the typing judgment to ensure there are no annotations in 1) the typing
result and the context, 2) the terms being compared by the algorithmic subtyping judgment, and3) the terms checked by the reduction relation (,→). However, if erasure is used in the typing
result of a premise using synthesis, i.e., Γ ` e ⇒ |A|, the original form of A requires guessing.
Referring to the original A in other premises renders the typing rule not algorithmic. Thus, we
make sure there is no such form of synthesis in the premises of typing rules. Note that the typing
rule is still algorithmic if the erased typing result appears in the conclusion of a synthesis rule ora premise using checking judgment.

5.4.2

Soundness and CompletenessWe show that the algorithmic subtyping and typing are both sound and complete to the originalunified subtyping. We use Γ ` e ⇔ A to denote a judgment which can either be the checking
judgment Γ ` e ⇐ A or the synthesis judgment Γ ` e ⇒ A. The main theorems are stated asfollows:
Theorem 5.4.1 (Soundness of Algorithm). If Γ ` e1 ⇔ A, Γ ` e2 ⇔ A and Γ ` e1 6 e2 , then|Γ| ` |e1 | 6 |e2 | : |A|.
Theorem 5.4.2 (Completeness of Algorithm). If Γ ` e1 6 e2 : A, then Γ ` e1 6 e2 and there
exists e10 and e20 such that Γ ` e10 ⇒ A and Γ ` e20 ⇒ A with |e10 | = e1 and |e20 | = e2 .

5.5. Subsumption of System F6
T∗ = A

Mapping of Type>∗ = >
X∗ = X(T1 → T2 )∗ = Πx 6 > : T1 ∗ . T2 ∗(x Fresh)(∀X 6 T1 . T2 )∗ = ΠX 6 T1 ∗ : ?. T2 ∗∆∗ = Γ

89t∗ = eMapping of Termx∗ = x(λx : T . t)∗ = λx 6 > : T ∗ . t ∗(t1 t2 )∗ = t1 ∗ t2 ∗(ΛX 6 T . t)∗ = λX 6 T ∗ : ?. t ∗(t[T ])∗ = t ∗ T ∗Mapping of Context∅∗ = ∅(∆, x : T )∗ = ∆∗ , x 6 > : T ∗(∆, X 6 T )∗ = ∆∗ , X 6 T ∗ : ?

Figure 5.9. Translation of System F6

5.5

Subsumption of System F6λI6 is a generalization of System F6 with dependent types. In this section, we show that λI6 cancompletely subsume the Kernel Fun variant [Cardelli and Wegner 1985] of System F6 . We firstshow the translation from System F6 to λI6 and prove that the typing and subtyping judgmentsof System F6 still hold in λI6 up to mapping. The full specification of System F6 was presented
in Section 2.4.2 (see Figure 2.3). The full proofs are available in Appendix A.2.

5.5.1

Translating System F6 to λI6

We show the mapping (denoted by ∗ ) of types, terms and contexts from System F6 to λI6 in
Figure 5.9. We use the metavariable T for types, t for terms and ∆ for contexts in System F6 . The
arrow type is non-dependent and unbounded and therefore mapped to a top-bounded function
type, similar to the treatment of syntactic sugar in Figure 5.2. The universal type is mapped to thedependent function type since X can appear in T2 . The bound T1 is a proper type and mapped toT1 ∗ with kind ?. The term and type abstraction, as well as term and type binding of the context,
are treated similarly. Other mappings hold few surprises.

5.5.2

Subsumption of Typing and Subtyping

We prove that the mapped typing and subtyping relations still hold in λI6 . The type system
of System F6 we used here is the algorithmic [Curien and Ghelli 1992] and Kernel Fun variant [Cardelli and Wegner 1985]. We first show the well-formedness of types and contexts still
hold after mapping:
Lemma 5.5.1 (Mapping of Well-formedness .). (1) If ∆ ` T , then ∆∗ ` T ∗ : ?; (2) If ` ∆, then` ∆∗ .
The proof is by simultaneous induction on the derivation of well-formedness of types ∆ ` T
and contexts ` ∆. Then we show the mapped subtyping and typing still hold:
Theorem 5.5.1 (Subsumption of Subtyping .). If ∆ ` T1 6 T2 , then ∆∗ ` T1 ∗ 6 T2 ∗ : ?.
Theorem 5.5.2 (Subsumption of Typing .). If ∆ ` t : T , then ∆∗ ` t ∗ : T ∗ .

Chapter 5. Unifying Typing and Subtyping90

The proof is straightforward by induction on the derivation of subtyping relation ∆ ` T1 6 T2
and typing relation ∆ ` t : T , respectively. Note that the mapped typing relation ∆∗ ` t ∗ : T ∗is syntactic sugar of unified subtyping relation, i.e., ∆∗ ` t ∗ 6 t ∗ : T ∗ (see Figure 5.2).

5.6

Discussion

In this section, we discuss alternative designs for λI6 and justify their trade-offs to the current
design.
Recursion and Recursive Types. The current syntax of λI6 does not contain any form ofrecursion. Adding recursion and recursive types is easy by simply following the treatment ofrecursion in PITS. We have an alternative formulation of our system (including full proofs) withthose features. However subtyping recursive types reveals an interesting problem. The typicalAmber rule [Cardelli 1986a], or even the following restricted invariant ruleΓ, x 6 > : A ` e1 6 e2 : A

Γ`A:?
S-MuI

Γ ` (µx : A. e1 ) 6 (µx : A. e2 ) : A

does not work well with λI6 . Here µx : A. e1 is a recursive type with the recursive binder x that
can appear in the body e1 . The rule requires the types of recursive binders to be the same. We
add a new reduction rule to unfold a recursive type: µx : A. e ,→ e[x 7→ µx : A. e]. In orderto keep type soundness, we need to ensure subtype preservation (Lemma 5.3.14) still holds. If
f = λy : ?. y is an identity type operator with type ? → ?, considerµx : ?. f x 6 µx : ?. > x
This relation holds by the rule S-MuI because we have f 6 > : ? → ? by S-Top and thenx : ? ` f x 6 > x : ? by S-App. Subtype preservation requires that the subtyping relation stillholds with both sides reduced by one step:f (µx : ?. f x) 6 > (µx : ?. > x)

(5.1)

However, (5.1) does not hold because the pointwise subtyping rule S-App requires arguments of
two applications should be the same. Thus, types are not preserved using the invariant rule forsubtyping recursive types. This issue appears to be common to most systems with higher-ordersubtyping [Pierce and Steffen 1997; Aspinall and Compagnoni 1996; Zwanenburg 1999], as it arises
from the interaction between the rules for recursive types and rules that use pointwise subtyping.
To solve this issue, we either change the S-App rule to be polarized [Steffen 1998], or only
allow subtyping two identical recursive types. The former approach is interesting, but requires amajor modification to the system. We leave that approach for future work (see Section 8.2). The
latter approach is relatively simple by using the following rule:Γ, x 6 > : A ` e : A

Γ`A:?
S-Mu

Γ ` (µx : A. e) 6 (µx : A. e) : A

Due to the unified syntax, µx : A. e can serve as both the term-level fixpoint and recursive type.
Though full subtyping of recursive types is not possible in λI6 currently, we are still able to5.6. Discussion

91

introduce general recursion and recursive types to the system with S-Mu. This is precisely theapproach used in our alternative formulation.
Operational Semantics. λI6 uses the same call-by-name (CBN) operational semantics thatcall-by-name PITS uses (see Section 4.1). However most OO languages use call-by-value (CBV).
CBV semantics is more complicated because of the existence of dependent types and explicit castsin λI6 . We also treat cast↑ [A] e as a value (see Section 5.2.2), which follows the standard callby-name semantics of iso-recursive types [Harper 2013]. Such design makes the cast↑ operator
computationally relevant (see Section 4.3.1). Alternatively, we can take the approach from callby-value PITS (see Section 4.2), which treats cast↑ [A] v as a value and adds a reduction rule tofurther reduce the inner term of cast↑ . However, the alternative semantics of cast↑ leads to more
complex reduction rules and metatheory. The cast canceling rule R-CastElim (See Figure 5.3)
now needs to check if the inner term of cast↑ is a value, which requires some non-trivial changes
to current proofs of the metatheory. We will later discuss the use of call-by-value casts for typing
strong dependent sums in the next chapter (see Section 6.1.2).
Top Types. For top types, we can alternatively treat only > as a value but not > e1 . . . en ,which is an inert term (see Figure 5.2). In such design additional reduction rules similar to theβ>-reduction rules of System F6ω [Pierce and Steffen 1997] are needed to further reduce “stuck”
terms to values, i.e., > e ,→ >. However, the approach of using β>-reduction needs to define
reduction rules for each form of stuck terms, e.g., > e and cast↓ >, while the definition of inert
terms deals with stuck terms in a more uniform way.
Weak vs Full Casts. Cast operators in λI6 use the same weak-head reduction for type-levelcomputation. As mentioned in Section 5.1.4, certain type conversions cannot be performed by
weak-head reduction/expansion if they require reduction at non-head position, e.g., converting
Vec (1 + 1) to Vec 2. To address this limitation we can use an alternative design from the full
PITS (see Section 4.3). Full PITS uses full parallel reduction is used in cast operators, which allows
reduction at any position of a term. However the metatheory of full PITS is significantly more
complicated than call-by-name/value PITS. Since weak-head reduction was simpler and sufficientfor our purposes (to model object encodings) we opted for that variant. It would be interesting tostudy the full-cast variant of PITS with subtyping as well in future work.
Full Contravariance of Function Types. As mentioned in Section 5.2.3, the unified subtyping
rule of function types is partially contravariant in the sense that bounds of function types are
identical, which follows the treatment of universal types in the Kernel Fun variant [Cardelli andWegner 1985] of System F6 . An alternative is to follow the full System F6 that allows bounds tobe contravariant:Γ ` A0 6 A : ?
Γ ` e0 6 e : A
Γ, x 6 e 0 : A0 ` B 6 B 0 : ?
0
0
Γ`e:A
Γ`e :AΓ`A:?
Γ, x 6 e : A ` B : ?
Γ ` (Πx 6 e : A. B ) 6 (Πx 6 e 0 : A0 . B 0 ) : ?

S-ProdF

We formulated an alternative system with such full contravariant rule and proved all lemmas in
Section 5.3 still hold. The corresponding Coq formalization can be found with the companion
materials of this thesis available online (See Section 1.5). However, full System F6 is proved to be

92

Chapter 5. Unifying Typing and Subtyping

undecidable [Pierce 1992]. With contravariance of bounds, λI6 using rule S-ProdF can subsume
full System F6 , rendering the system undecidable. Though we have not proved the decidability of
λI6 yet, we adopt the Kernel-Fun rule in λI6 and can at least rule out the undecidability causedby the full contravariance.

93

CHAPTER

6

Iso-Types with Strong Dependent Sums

In this chapter, we present the λIΣ calculus. The motivation of proposing λIΣ is to model OOP
structures with abstract type members using dependent types and strong dependent sums. The
λIΣ calculus is a variant of λI6 and enables the combination of strong sums and dependent types.
It is based on the ideas of iso-types and unified subtyping. λIΣ employs the PTS-style unified
syntax and contains the single sort ? and the “type-in-type” axiom as in λI6 . Moreover, λIΣsupports impredicative polymorphism with strong sums, which usually cannot be supported
simultaneously by previous work [Harper and Mitchell 1993; Stump 2017; Bowman et al. 2017].
Impredicativity and strong sums together lead to logical inconsistency [Coquand 1986; Hook andHowe 1986] and breaks strong normalization. Moreover, some dependently typed calculi with
subtyping, such as λP6 [Aspinall and Compagnoni 1996] and λΠ6 [Chen 1998], rely on strong
normalization to prove many desirable properties, such as transitivity and subject reduction,
which will be lost if both impredicativity and strong sums are allowed. In contrast λIΣ uses the
iso-type approach that decouples proofs from strong normalization. It enjoys the same desirable
properties as λI6 , e.g., transitivity of subtyping and type-safety, which can be proved in theabsence of strong normalization.
Iso-types are used in λIΣ to type destructors of strong sums. We call this form of strongsums iso-strong sums. Unlike the call-by-name casts in λI6 , call-by-value casts are used in λIΣ
for type conversions of strong sums. The typing results of strong destructors (i.e. the second
projection and strong opening) are intermediate type-level applications instead of standard direct
substitutions. This makes it possible to solely use call-by-value casts for the required type-levelcomputation instead of full casts. Using call-by-value casts also makes it easy to combine unified
subtyping and avoids the complex metatheory of full casts.
Notice that for simplicity reasons, several features are dropped in λIΣ so as to focus on
the development of dependent sums, such as generalized top type and bounded quantification.
Nevertheless, λIΣ is still expressive enough to encode Scala-like type members and traits. Finally,for demonstration purposes, we create a lightweight surface language Sig built on top of λIΣ . Sig
supports Scala-like type members, path-dependent types and traits by a type-directed elaborationthat produces type-sound λIΣ terms.

Chapter 6. Iso-Types with Strong Dependent Sums

94

Table 6.1. Properties of dependently typed calculi with beta equality
FeaturesΠ+Impredicativity

Example Calculi
λC

Π+Σ+Impredicativity

λC with strong sums

Π+Subtyping

λP6 and λΠ6Π+Σ+Subtyping+
Impredicativity

No known calculus

6.1

Properties
Subject Reduction does not depend on Strong Normalization.
No Strong Normalization or Logical Consistency, but
Subject Reduction holds.
Transitivity & Subject Reduction depend on Strong
Normalization.
Strong Normalization, Transitivity & Subject
Reduction may not hold.

Overview

In this section, we informally present features of λIΣ . The motivation of developing the λIΣ calculus is to support various features of strong dependent sums, which are useful to model many
language constructs, including type members and traits in Scala [Odersky et al. 2004], as well as
various features of module systems in ML [MacQueen 1986]. However, it is non-trivial to combine
strong sums, dependent types and subtyping in a single system. We briefly discuss such problem
and present our solution in λIΣ , i.e. iso-strong sums that utilize call-by-value casts without theneed of full casts. We show how to encode modular structures with strong sums by examples
written in Sig, a lightweight surface language built on top of λIΣ . The formal presentation of
λIΣ and Sig will be in Sections 6.2 and 6.4, respectively.

6.1.1

The Trouble with Impredicativity and Strong Sums

Strong sum types (Sigma-types) bring extra expressiveness over dependent function types (Pitypes). However, it is non-trivial to combine strong sums with dependent type systems and keep
desirable properties. For example, the calculus of constructions (λC) with strong sums is logicallyinconsistent [Coquand 1986; Hook and Howe 1986], since the inclusion of strong sums leads tothe subsumption of the “type-in-type” axiom. The subsumption of “type-in-type” is enabled by
the combination of strong sums and impredicativity. A system is impredicative if it contains animpredicative sort s where certain types of sort s have quantifiers of the sort s itself [Adams
2008]. For example, the sort ? in λC is an impredicative sort since Πx : ?. x has type ?. As aresult, strong normalization does not hold in such system and some other properties may also be
lost, e.g., the decidability of type checking, which is entangled with the normalization property in
λC (also other PTS) [van Benthem Jutting 1993].
The Problem of Adding Subtyping. Subtyping is a desirable language feature to support,
which is crucial for modeling parametric polymorphism in OOP or information hiding in ML
modules [Dreyer 2005; Leroy 1994]. However, combining subtyping and dependent types isalready difficult (see Section 5.1.2), resulting in a more complex metatheory. In certain calculi that
support both dependent types and subtyping, several important metatheory results depend on
strong normalization. For example, in λP6 [Aspinall and Compagnoni 1996] and λΠ6 [Castagna
and Chen 2001; Chen 1998], both subject reduction and transitivity of subtyping rely on strong
normalization. In contrast, λC and also PTS do not require strong normalization to prove subject
reduction. We summarize the properties of previously mentioned calculi in Table 6.1 where Π6.1. Overview

95

stands for dependent function types and Σ stands for strong sum types. The situation becomes
more complex when further considering to combine subtyping and strong sums. If we add strongsums to calculi such as λP6 and λΠ6 , allowing impredicativity will break strong normalizationand eventually break subject reduction and transitivity, as indicated by the last row of Table 6.1.
Thus, it becomes rather difficult to simultaneously allow impredicativity, subtyping and strongsums and keep all desirable properties in such calculi.
Previous Solution: Abandoning Impredicativity. One approach to supporting strong sums
without breaking logical consistency and strong normalization is to abandon impredicativity. For
example, Harper and Mitchell [1993] proposed XML, an extension of Standard ML with strong
sums, which supports only predicative polymorphism by stratifying types into different universes.
Dropping impredicativity is reasonable in the context of an ML-like language, since predicativity
is crucial for other language features, e.g., let-polymorphism and type inference. However, such
restriction still significantly limits the expressiveness of the language, making it unable to fully
subsume System F or F6 which both supports impredicative polymorphism.

6.1.2

Iso-Strong Sums: Typing Strong Sums with Iso-Types

Unlike the previous work, λIΣ features iso-strong sums, which employs the iso-type approach anduses explicit call-by-value cast operators for type-level computation with strong sums. By using
iso-types, the metatheory proofs are decoupled from strong normalization (see Sections 3.1.3
and 5.1.4). In λIΣ , we can prove transitivity of (unified) subtyping and subject reduction without
requiring normalization (see Section 6.3). Thus, impredicative polymorphism, (iso-type style)strong sums and (unified) subtyping can coexist in λIΣ without breaking desirable properties. In
the rest of this subsection, we show how iso-strong sums are typed in λIΣ through call-by-value
casts.
Standard Typing of Second Projection. The typing of strong dependent sums involves typelevel computation. Specifically, the type of the second projection of a term depends on its firstprojection. It is the key complication over weak sums which do not support second projection
but only weak existential opening. Given a term e that has a Sigma-type, the standard typing of
its second projection e.2 is shown as follows:Γ ` e : Σx : A. B
Γ ` e.2 : B [x 7→ e.1]
where the type of e.2 is a substitution and depends on e.1. Consider an expression e which isexactly a dependent sum, i.e.,e = he1 , e2 as Σx : A. B i
e1 : Ae2 : B [x 7→ e1 ]Chapter 6. Iso-Types with Strong Dependent Sums

96

where the type of the second component depends on the first. Noting that the first projection e.1
can be reduced to the first component e1 , we need type-level computation to convert e.1 into e1 :
he1 , e2 as Σx : A. B i.1 ,→ e1
e.2 : B [x 7→ he1 , e2 as Σx : A. B i.1]
e.2 : B [x 7→ e1 ]After conversion, the type of e.2 matches the type of e2 and the reduction he1 , e2 as Σx :A. B i.2 ,→ e2 preserves the type.
Second Projections and Alpha Equality. In λIΣ , there is no implicit type conversion and
we need to add cast operators explicitly for such conversion:e.2: B [x 7→ he1 , e2 as Σx : A. B i.1]
cast⇓ (e.2) : B [x 7→ e1 ]The full cast⇓ operator1 from the full PITS (see Section 4.3) is required here, which utilizes parallel
reduction. The call-by-name/value reduction is not congruent and not strong enough to convert
such types inside the substitution. For example, consider e = hInt, (λy : Int. y) as Σx : ?. (x →x )i. Then we have e.1 ,→ Int ande: Σx : ?. (x → x )e.2: (e.1) → (e.1)
cast⇓ (e.2) : Int → Int
Notice that the type of e.2 is a Pi-type (i.e. Πy : (e.1). (e.1)) which is not reducible by callby-name/value reduction. However, as discussed in Section 4.3, using full casts significantly
complicates the metatheory and makes it difficult to support subtyping. With full casts, one relies
on a separate system that erases all casts for proving type soundness. The technique of unified
subtyping that uses iso-types does not apply in such erased system, making it hard to proverelevant properties, such as transitivity and subject reduction. We still prefer call-by-name/value
reduction for explicit casts, which is compatible with the existing method of unified subtyping.
Typing Second Projection with CBV Casts. Alternatively to full casts, we can slightly
weaken the type of second projection and make it convertible with call-by-value casts. The
approach is to “take one step back” by changing the type substitution back into an application
form as follows2 :Γ ` e : Σx : A. B
Γ ` e.2 : (λx : A. B ) (e.1)
The original standard type “B [x 7→ e.1]” can be imagined as a reduced term of the current type.
The new typing result of e.2 can be seen as an intermediate step where e.1 is not yet substituted
into B and remains as an argument. Thus, we can use call-by-value reduction to further reduce e.1
1

For brevity, we leave out the annotation of cast⇓ .
The rule presented here is for demonstrating the idea of typing and is a bit different from the one used in λIΣ . It
does not employ the value restriction, i.e., requiring e to be a value v. We will later discuss the value restriction of λIΣ
in Section 6.2.
2

6.1. Overview

97

until it becomes a value. For example, suppose that e is a dependent sum whose first component
is a value:e = hv1 , e2 as Σx : A. B ie.2 : (λx : A. B ) (hv1 , e2 as Σx : A. B i.1)
Note that a dependent sum is already a value. We can use two consecutive call-by-value cast↓operators to obtain the desired type:e.2: (λx : A. B ) (hv1 , e2 as Σx : A. B i.1)
cast↓ (e.2) : (λx : A. B ) v1
cast2↓ (e.2) : B [x →7 v1 ]
Specifically, we use one cast for reducing the first projection and the other cast for beta reduction,i.e.,
hv1 , e2 as Σx : A. B i.1 ,→ v1(λx : A. B ) v1,→ B [x 7→ v1 ]The type of cast2↓ (e.2) matches the type of e2 . In the reduction rule for hv1 , e2 as Σx : A. B i.2,
we need to correspondingly add two extra cast↑ operators for the reduced term needs to balance
the type:
he1 , e2 as Σx : A. B i.2 ,→ cast2↑ e2Then the whole reduction process preserves the types:
cast2↓ (hv1 , e2 as Σx : A. B i.2) ,→ cast2↓ (cast2↑ e2 ) ,→ ... ,→ e2
Thus by weakening the substitution form into a type-level application, we can now convert
the type of second projection using non-congruent call-by-value reduction without the need offull parallel reduction. The trade-off is that we need more type conversion steps with CBV castthan full casts, e.g., two call-by-value cast↓ operators but only one cast⇓ in the example above.
Nevertheless, CBV casts are still able to perform necessary type conversions for strong sums.
Also, subtyping in λIΣ can be supported by applying the technique of unified subtyping which iscompatible with CBV casts.

6.1.3

Example: Type Members and Traits

In Sections 1.3.3 and 2.2.3, we showed that Scala-like traits with type members can be encodedusing dependent sums. Recall the example of an abstract integer set trait. We can write the same
example in Sig, a simple surface language over λIΣ , as follows:
Set = trait {type T: Type;val empty: T;
val member: Int -> T -> Bool;val insert: Int -> T -> T;}

We use monospaced font for Sig programs. We can translate Set to a Sigma-type in λIΣ (assumingthat we have records and primitive types such as integers and booleans):
Set = ΣT : ?.{Chapter 6. Iso-Types with Strong Dependent Sums

98
empty : T ,member : Int → T → Bool ,insert : Int → T → T ,}The type member T corresponds to the type binder of the Sigma-type. The methods of the trait
are encoded as record members of the record type: empty returns an empty set; member checks if
an element is in the set; and insert adds an element into the set. We can also write the genericfunction f from Section 2.2.3 in Sig:
f = λ(s:Set) => s.member 3 (s.insert 3 s.empty)

which is encoded in λIΣ by the open operator, a stronger version of the unpack operator of
weak sums:
f = λs : Set. open s as hT , s 0 i in s 0 .member 3 (s 0 .insert 3 s 0 .empty)

Limitations of Weak Sums. The examples by far can be encoded using only weak sums.
However, weak sums are not sufficient to encode all type member features in Scala, such as
path-dependent types. The function f is encodable by weak sums because the type of the wholefunction body is Bool and does not contain the abstract type member T . Recall the same function
g from Section 2.2.3, a simple function that returns an empty set:g = λ(s:Set) => s.empty

Note that the type of the function body now refers to the abstract type member. In Scala, the typeof s.empty is s.T, which is a path-dependent type. We cannot translate s.empty with weak sums,
such as “unpack s as [T , s 0 ] in s 0 .empty”, because s 0 .empty has type T which is out of thescope of the unpack-term.
Encoding with Iso-Strong Sums.

In λIΣ , we can encode g with open:g = λs : Set. open s as hT , s 0 i in s 0 .empty
Unlike unpack, the open operator permits the body to refer to the abstract type member T . In
λIΣ , the type of g is as follows:g : Πs : Set. (λT : ?. T ) (s.1)
where s.1 is the projection of the first component of s. Similarly to the treatment of typing second
projection (see Section 6.1.2), the type of strong open is a type-level application: (λT : ?. T ) (s.1).
Essentially, we know that the type of the open-term should be the same as the actual typemember of s, i.e. s.1, the first component of s. But s is abstract and we do not know what theactual type member is yet. The type-level application can be viewed as an intermediate step, which
is waiting for the actual implementation of s. Once s is given, we can continue the type-levelcomputation with explicit casts to obtain the final type. Consider s is instantiated by ListSet, a
set implementation using a list. We borrow the syntax of Haskell’s list type and functions in thefollowing Sig pseudo-code:6.1. Overview

99

ListSet = obj {type T = [Int];val empty = [];val member = elem;val insert = (:);}

which is translated to a dependent sum in λIΣ :ListSet = h[Int ], {empty = [ ], member = elem, insert = (:)} as Seti
Two components of the dependent sum are wrapped by angle brackets and separated by a comma.
The type annotation Set is put after the keyword as. Then the first projection of ListSet is its
first component [Int ], i.e., ListSet.1 ,→ [Int ]. We can eliminate the type-level application as
follows:
g ListSet: (λT : ?. T ) (ListSet.1)
cast↓ (g ListSet) : (λT : ?. T ) [Int ]cast2↓ (g ListSet) : [Int ]which needs two consecutive cast↓ operators to obtain the target type: one for reducing the firstprojection, and the other one for reducing the application.
We emphasize three points from the translation of g:• First, the encoding of g relies on the exclusive features of strong sums in λIΣ , thus cannot
be encoded with weak sums in λI6 .
• Second, the reduction relation used in cast↓ is call-by-value, which reduces the argument
into a value before beta-reduction. Using call-by-value casts is more appropriate here
because call-by-name reduction cannot reduce the argument and does not meet the purpose.
The full cast with parallel reduction is over powerful and complicates the metatheory (seeSection 4.3), which makes it difficult to combine with other features, such as subtyping.
• Third, we use a strong open operator here instead of the second projection (see Section 2.2.3)
due to the typing of iso-strong sums. Otherwise, the typing result of the second projectionof a iso-strong sum is a type-level application but not directly a record type. This forbids us
to do further record projection to obtain the field empty. We will later discuss this issue inSection 6.2.3.

6.1.4

ML Module Systems and Strong Sums

The ML family of languages, such as Standard ML [Milner et al. 1990] and OCaml [Leroy et al.
2018], usually contains an advanced module system. The basic constructs are signatures, structuresand functors. A structure is a module that consists of types and values. A signature is the type of astructure, containing the specification for each component of the structure. A functor is a function
from structures to structures. Many languages have similar constructs to ML modules. For
example in Scala (also Sig), traits correspond to signatures and objects correspond to structures.
The Sig examples in Section 6.1.3, i.e., Set trait and ListSet object, can be easily adapted toconstructs of the module system in OCaml:

Chapter 6. Iso-Types with Strong Dependent Sums

100

module type Set = sig
type tval empty: t
val member: int -> t -> bool
val insert: int -> t -> t
end

module ListSet = structtype t = int list
let empty = []let member = List.mem
let insert x l = x :: lendFunctions of objects correspond to functors. For example, the function g can be modeled as afunctor G that takes a Set parameter and returns a new structure wrapping the actual function g:
module G(S:Set) = struct
let g = S.empty
end

The function application g ListSet can be simulated by a functor application G(ListSet):
let module M = G(ListSet) in M.g

First-class Modules. In a certain sense, we can treat Sig as a very simple ML-like module
system, though many features are missing in Sig, such as transparent types [Lillibridge 1997;
Leroy 1994; Harper and Lillibridge 1994; Harper and Mitchell 1993]. It is not a coincidence since
ML modules can also be modeled by strong dependent sums [MacQueen 1986]. Specifically,“modules” (objects indeed) are first-class values in Sig. Usually, ML modules are second-class andseparated from terms and types. The core language of ML cannot freely manipulate modules, e.g.,choosing modules at run-time:
module FastSet = if size > 20 then HashSet else ListSet

In Sig, there is no such restriction and modules/objects can be even more expressive due todependent types. It is possible to define a trait such that the type of trait members can depend onvalues, for example:
BitMap = trait {type Dim: {m:Int, n:Int};
val pixels: Array<Dim.m, Dim.n>;}

The dimension type Dim is a record with two integers, which represents maximum rows andcolumns of a bitmap. The member pixels is a two-dimensional bit array that stores the data.
The array type is a dependent type: it depends on the numbers m and n given by Dim. The BitMap
trait encapsulates the information of dimensions. All BitMap objects have the same type, even if
their dimensions are different. This makes it easier to define generic functions on the trait thanthe dependently-typed array type, i.e., Array<m, n>, since arrays have different types if theirdimensions are not the same.

6.2

The λIΣ Calculus

In this section, we formally introduce the λIΣ calculus, a variant to λI6 with iso-strong sums. λIΣkeeps core features of λI6 , including iso-types, unified syntax and unified subtyping. To focus on
the support of dependent sums and simplify the metatheory, several features are dropped, suchas bounded quantification and generalized top type. λIΣ also features a call-by-value semantics

6.2. The λIΣ Calculus

101

for type casts, which enables the typing of second projection on dependent sums. The value
restriction is employed similarly to call-by-value PITS. We present the syntax, dynamic and static
semantics of λIΣ in the rest of this section.

6.2.1

SyntaxThe syntax of λIΣ is shown in Figure 6.1. Similarly to λI6 , there is no distinction between terms
and types. The novelties over λI6 are language constructs for dependent sums. We follow thesimilar convention that metavariables are lowercase for terms and uppercase for types.
Dependent Sums. The dependent sum type, i.e., Sigma-type, is denoted by Σx : A. B . Dependent sums are denoted by he1 , e2 as Σx : A. B i with the dependent sum type annotatedafter the as keyword. The type annotation is provided to simplify typing and reduction rules. As
mentioned in Section 5.1.5, only weak dependent sums can be encoded. To obtain native support
for strong dependent sums, we treat both constructs as primitives in λIΣ .
Projection and Opening. λIΣ supports two kinds of operations on dependent sums: projection
and opening. Dependent sum types can be seen as a generalization to both product type A × B
and existential type ∃x.B. The projection operator follows the dot syntax commonly used forpairs. The first (second) projection e.1 (e.2) extracts the first (second) component of the dependent
sum e. The unrestricted second projection e.2 can only be supported with strong dependent sums.
The opening expression open e1 as hx , yi in e2 follows the semantics of existential opening,which is similar to a pattern-matching binding. Expression e1 is destructed into first and second
components, which are bound to pattern variables x and y, respectively. The pattern variables
can be used in another expression e2 . The opening operation is strong in the sense that x canshow in the type of e2 , which is prohibited by the scoping restriction of weak existential opening.
Both projection and opening are destructors of dependent sums and their usage may overlap.
For example, we will show the second projection can actually be expressed by strong opening(see Section 6.2.3). We keep an individual form of the second projection for better presenting thesystem. However, we cannot leave out the form of the first projection, which is used in the typing
result of second projection and opening (see Figure 6.3).
Other Changes to λI6 . There are several simplifications in λIΣ for focusing on discussion of
dependent sums. We drop bounded quantification, which is an orthogonal feature to dependentsums. This significantly simplifies the syntax since the binder does not need to contain subtyping
constraints. The definition of the context Γ only contains type bindings x : A. Without thedemand to unify two forms of binders in λI6 (i.e. λx : A. e and λx 6 e 0 : A. e), we also drop thegeneralized top type that allows > to have any type. In λIΣ , > is only a type and has kind ?. The
ordinary top type also makes type-safety proofs easier (see Section 6.3.3). Finally, we drop the
annotation in the cast↑ operator for simplifying reduction rules (see Section 6.2.2). Though typechecking an unannotated cast↑ expression is not algorithmic, the unified subtyping judgment isdeclarative anyway due to the subsumption rule (see Section 6.2.3).

Chapter 6. Iso-Types with Strong Dependent Sums

102::= x | ? | > | e1 e2 | cast↑ e | cast↓ e|
λx : A. e | Πx : A. B|
Σx : A. B | he1 , e2 as Σx : A. B i|
e.1 | e.2 | open e1 as hx , yi in e2
Γ::=∅ | Γ, x : Av::=? | x | > | λx : A. e | Πx : A. B|
cast↑ e | Σx : A. B | hv , e as Σx : A. B i
A → B , Πx : A. B where x 6∈ FV(B )e, A, B

Expressions

Contexts
ValuesSyntactic Sugar

Figure 6.1. Syntax of λIΣ
(Partially Call-by-Value Reduction)

e1 ,→ e2
RP-AppL

RP-AppR

RP-Castdn

e ,→ e 0
e v ,→ e 0 v

e2 ,→ e20
e1 e2 ,→ e1 e20

e ,→ e 0
cast↓ e ,→ cast↓ e 0

RP-Beta(λx : A. e) v ,→ e[x 7→ v ]RP-Fste ,→ e 0
e.1 ,→ e 0 .1

RP-CastElim

cast↓ (cast↑ e) ,→ e

RP-Proj1

hv , e as Σx : A. B i.1 ,→ v

RP-Proj2

hv , e as Σx : A. B i.2 ,→ cast↑ (cast↑ e)
RP-Openopen hv , e1 as Σx : A. B i as hx , yi in e ,→ cast↑ (cast↑ (((λx : A. λy : B . e) v ) e1 ))Figure 6.2. Operational semantics of λIΣ

6.2.2

Dynamic Semantics

The reduction relation ,→ is shown in Figure 6.2. Similarly to λI6 , ,→ is used for both typeconversion in casts and term evaluation. The difference is that ,→ in λIΣ is partially call-by-value,
which is mostly call-by-value along with several call-by-name rules. The reduction rules related
to function applications are rightmost call-by-value, also called right-to-left call-by-value [Leroy1990]. RP-Beta requires the argument to be a value. Arguments are reduced first in RP-AppRand functions can be further reduced in RP-AppL when arguments are values. Note that we use
the metavariable v to range over values. The syntax of values is defined in Figure 6.1. As in
call-by-value PITS, variables are values, which enables reduction with open terms (see Section
4.2.2).
Other reduction rules related to casts and dependent sums are call-by-name, which do not
reduce sub-terms to values as in λI6 . RP-Proj1 only accepts a dependent sum that is a value
where its first component is a value. RP-Fst reduces sub-terms of first projections but there is nosuch rule for second projections. This is due to a value restriction [Swamy et al. 2011; Sjöberg et al.
2012]: we only treat hv , e as Σx : A. B i and v .2 as well-typed terms. RP-Proj2 and RP-Openboth add two consecutive cast↑ operators (also written as cast2↑ ) in reduced terms to preserve
types. We will discuss value restriction and typing related issues later in Section 6.2.3.
The major reason of using the non-standard partially call-by-value semantics is to ensure
type-safety, especially the subtype preservation lemma (see Lemma 6.3.9). Using the rightmost

6.2. The λIΣ Calculus

103

style of call-by-value semantics is not a necessity but simplifies the proof for subtype preservation.
The common leftmost/left-to-right call-by-value semantics can also be used in λIΣ but at theexpense of more complex proofs and incompatibility with other language features such as bounded
quantification. Moreover, there are other useful applications of the rightmost variant, e.g., for an
efficient implementation of multiple application in ML [Leroy 1990]. We will discuss these issues
later in Section 6.3.3.

6.2.3

Static Semantics

Figure 6.3 shows the static semantics of λIΣ , i.e., unified subtyping Γ ` e1 6 e2 : A and context
well-formedness ` Γ. Similarly to λI6 , unified subtyping is a single judgment that combines bothtyping and subtyping. The typing judgment Γ ` e : A is syntactic sugar for Γ ` e 6 e : A. The
context well-formedness judgment ` Γ ensures every newly added type binding x : A is freshand A is a well-formed type. Note that there is no bounded quantification in λIΣ and only typebinding is supported in Γ. For the unified subtyping judgment, we focus on the discussion of newrules about dependent sums and other differences to λI6 , e.g., value restriction.
Variables and Top Types. As bounded quantification is not supported in λIΣ , assumptions
about subtyping cannot be added into the context. Thus, there is no subtyping of variables as
indicated by SP-Var, i.e., the subtype of a variable is itself. As mentioned in Section 6.2.1, top typesin λIΣ are now just ordinary types with kind ? as in SP-Top and SP-TopRefl. The simplificationof rules for variables and top types also eases the metatheory proof, as discussed in Section 6.3.1.
Value Restriction. Unlike the call-by-name semantics of λI6 , we use a (partially) call-by-value
semantics in λIΣ and employ value restriction as in call-by-value PITS to ensure type preservation
in a simple way (see Section 4.2.1). There are two rules for function applications, SP-App for
non-dependent ones and SP-AppV for dependent ones. Dependent functions can only be applied
to value arguments, while there is no restriction for non-dependent functions. Also, variables aretreated as values (see Figure 6.1) as in call-by-value PITS, which enables reduction of open terms(e.g. (λx : Int. x ) y) in call-by-value semantics. As a result, when doing substitutions, substitutes
must be values in order to maintain the computational behavior of variables.
Dependent Sums. SP-Sigma checks the well-formedness of dependent sum types (i.e. Sigmatypes). The binder x can show in the body B1 or B2 . Like rule SP-Abs for subtyping functions,
we limit the subtyping of Sigma-types to be pointwise, which requires the types of binders to be
identical. This is different from subtyping Pi-types in rule SP-Prod, where the argument types
are contravariant.
SP-Pair defines the constructor of dependent sums, which also uses pointwise subtypingthat fixes the first component. A dependent sum allows the first component (v ) to show in thetype of the second component (e1 and e2 ). The type of the second component is a substitution
B [x 7→ v ] and the substitute v, i.e., the first component, must be a value since variables are values(see Figure 6.1).
Projections. SP-Fst and SP-Snd are the rules for first and second projection, respectively.
Allowing the typing of second projection indicates dependent sums in λIΣ are strong. In rule SPSnd, we follow the design of pointwise subtyping and disable the subtyping of second projection

Chapter 6. Iso-Types with Strong Dependent Sums104
Γ ` e1 6 e2 : A(Unified Subtyping)

SP-Ax

SP-VarSP-Top

SP-TopRefl`ΓΓ`?6?:?

`Γx :A ∈ ΓΓ`x 6x :AΓ`e:?
Γ`e6>:?

`ΓΓ`>6>:?

SP-AbsSP-AppΓ`A:?
Γ, x : A ` e1 6 e2 : B
Γ, x : A ` B : ?
Γ ` (λx : A. e1 ) 6 (λx : A. e2 ) : Πx : A. B

Γ ` e1 6 e2 : A → BΓ ` e3 : A
Γ`B :?
Γ ` e1 e3 6 e2 e3 : B

SP-Prod
SP-AppVΓ ` e1 6 e2 : Πx : A. B
Γ`v :AΓ ` e1 v 6 e2 v : B [x 7→ v ]Γ ` A2 6 A1 : ?
Γ, x : A1 ` B1 : ?
Γ, x : A2 ` B1 6 B2 : ?
Γ ` (Πx : A1 . B1 ) 6 (Πx : A2 . B2 ) : ?

SP-Castup

SP-CastdnΓ`B :?
Γ ` e1 6 e2 : A
B ,→ AΓ ` cast↑ e1 6 cast↑ e2 : BΓ ` e1 6 e2 : A
A ,→ BΓ ` cast↓ e1 6 cast↓ e2 : B

SP-Pair
SP-SigmaΓ`A:?
Γ, x : A ` B1 6 B2 : ?
Γ ` (Σx : A. B1 ) 6 (Σx : A. B2 ) : ?

Γ`v :AΓ ` e1 6 e2 : B [x 7→ v ]Γ`A:?
Γ, x : A ` B : ?
Γ ` hv , e1 as Σx : A. B i 6 hv , e2 as Σx : A. B i : Σx : A. B

SP-FstSP-SndΓ ` e1 6 e2 : Σx : A. B
Γ ` e1 .1 6 e2 .1 : AΓ ` v : Σx : A. B
Γ ` v .2 6 v .2 : (λx : A. B ) (v .1)

SP-OpenΓ ` v : Σx : A. B
Γ, x : A, y : B ` e : CΓ`A:?
Γ, x : A ` B : ?
Γ, x : A ` C : ?
Γ ` open v as hx , yi in e 6 open v as hx , yi in e : (λx : A. C ) (v .1)
SP-SubΓ ` e1 6 e2 : A
Γ`A6B :?
Γ ` e1 6 e2 : B`Γ(Well-formedness)
WP-Cons
WP-NilΓ`A:?
x fresh in Γ
` Γ, x : A`∅

Syntactic Sugar

Γ`e:A,Γ`e6e:A

Figure 6.3. Static semantics of λIΣ
by requiring both sides of the relation to be the same. We also employ value restriction andrequire the dependent sum to be a value. The reason is similar to rule SP-AppV. The typing
result of SP-Snd is dependent on the form of input terms. Pointwise subtyping simplifies the ruledefinition (see Section 5.2.3). Restricting input terms as values forbids the reduction of sub-terms
in second projection, which ensures type preservation (see Section 4.2.1).
Assume that we drop the value restriction for typing second projections and allow reducing

6.2. The λIΣ Calculus

105

the sub-terms of second projections as follows:
e ,→ e 0
e.2 ,→ e 0 .2
Then e.2 and e 0 .2 have different types due to lack of beta-equivalence, since their types contain e
and e 0 , respectively, which breaks type preservation.
Iso-strong sums use a different typing rule for the second projection. The typing of second
projection is different from the standard definition:Γ ` v : Σx : A. B
Γ ` v .2 : B [x 7→ v .1]
where the typing result is a substitution B [x 7→ v .1]. As mentioned in Section 6.1.2, in order toavoid the use of full casts with parallel reduction, we do not use the standard typing rule abovethat involves direct type substitution. In SP-Snd, the typing result is a type-level application,i.e., (λx : A. B ) (v .1). Note that the typing result is well-formed since λx : A. B is a nondependent function where B has type ? with no x . The type-level application can be viewed as anintermediate step before substitution. We can use explicit type casts to obtain the final substituted
type. For example, consider v is a dependent sum v = hv 0 , e 0 as Σx : A. B i. Notice that thefollowing reduction steps hold:
hv 0 , e 0 as Σx : A. B i.1 ,→ v 0(λx : A. B ) v 0 ,→ B [x 7→ v 0 ]We can add two consecutive cast↓ operators to obtain the substituted type:v .2 : (λx : A. B ) (hv 0 , e 0 as Σx : A. B i.1)
cast2↓ v .2 : B [x 7→ v 0 ]The type of cast2↓ v .2 follows the premise in SP-Pair for typing second component. Recall thatthe reduction rule for second projection, i.e., RP-Proj2, adds two cast↑ s, which exactly balance
the manually added two cast↓ s:v .2 ,→ cast2↑ v 0,→ cast2↓ (cast2↑ v 0 ) ,→ v 0

cast2↓ v .2

Thus, we can achieve type-preserving reduction for the second projection through explicit casts.
Openings. SP-Open is the rule for the opening operation, an alternative to projection for
destructing a dependent sum. It has the same restrictions as SP-Snd: value restriction and no
subtyping. The typing result is also similar, which adopts the approach of iso-strong sums andis a type-level application. Two pattern variables x and y correspond to the first and second
component of a dependent sum v, respectively. The inner term e is typed as C against patternvariables with typing x : A and y : B. Note that we only allow x to show in C but not y, which
is checked by the last premise. Such restriction ensures the typing result, i.e., (λx : A. C ) (v .1),
will not be out of scope. Despite of such restriction, the opening operation is still more expressiveChapter 6. Iso-Types with Strong Dependent Sums

106

than the ordinary existential opening that even does not allow x to show in C. Opening operation
can be seen as a generalization of second projection:v .2 = open v as hx , yi in ywhere both sides have the same typing result. Opening allows directly using the type of thesecond component as a pattern variable y inside e, while the type of second projection is anapplication that cannot be directly used. For example, imagine that v is a dependent sum whose
second component is a function that takes an integer:v : Σx : ?. Int → x
The second projection of v has typev .2 : (λx : ?. Int → x ) (v .1)
which cannot take an integer, say (v .2) 3. In λIΣ , we use opening instead:open v as hx , yi in (y 3) : (λx : ?. x ) (v .1)
where the pattern y can take an integer since y : Int → x .
No Nested Second Projections. The value restriction simplifies the metatheory but unfortunately limits the ability of nesting second projections in λIΣ . For example, (v.2).2 is not awell-formed term since v.2 is not a value. Furthermore, we cannot use openings to simulate
nested second projections either. Consider the following example:v
open v as hx1 , yi inopen y as hx2 , zi in z::

Σx1 : A1 . (Σx2 : A2 . B )( λx1 : A1 .
(λx2 : A2 . B) (y.1) ) (v.1)

We simulate nested second projections (v.2).2 by two consecutive openings. However, the typing
result is not well-formed since the pattern variable y leaks out of the scope. This violates the
restriction imposed by the last premise of SP-Open, which requires that the second patternvariables (e.g. y) should not show in the result type.
Notice that nested first projections are still allowed. Iso-strong sums are still more expressive
than weak sums and sufficient for our purposes to encode interesting examples such as traits with
type members (see Section 6.1.3). Restricting nested projections is also used by other calculi tosimplify the presentation and metatheory. For example, DOT [Rompf and Amin 2016; Amin et al.
2016] only supports a single level of type selection on variables such as x.A. Removing value
restriction and supporting nested second projections are left as future work (see Section 8.2).
No Direct Subsumption of Non-dependent Pairs. Finally, due to the non-standard typing
in SP-Snd and SP-Open, iso-strong sums in λIΣ cannot directly subsume non-dependent pairs
or ordinary weak existentials. Consider a non-dependent pair v = h1, 2 as Σx : Int. Inti. By
the standard typing rule, the type of v .2 is Int[x 7→ v .1] = Int where the substitution has noeffect and the typing result is the same as non-dependent pairs. In contrast, by SP-Snd we have

6.3. Metatheory of λIΣ

107v .2 : (λx : Int. Int) v .1, where the typing result is still a type-level application but not Int.
Nonetheless, we can add explicit casts to recover the standard typing results as examples above(see also Sections 6.1.2 and 6.1.3). Alternatively, we can just encode typing rules for non-dependentpairs and weak existentials using standard Church encodings [Pierce 2002].

6.3

Metatheory of λIΣ

We discuss the metatheory of the λIΣ calculus, mainly on two results: transitivity and type-safety.
The proof process is mostly similar to the one of λI6 (see Section 5.3). However, due to differencesof dynamic and static semantic, especially call-by-value reduction and dependent sums, λIΣrequires additional lemmas and some changes in proof strategies. We will focus on discussion ofsuch changes from the metatheory of λI6 . Note that we have not proved the decidability of λIΣ
yet, though we believe the property should hold and leave it as future work (see Section 8.2).

6.3.1

Basic Lemmas

We first discuss the changes to basic lemmas compared to λI6 . Due to the absence of bounded
quantification, some basic lemmas now can be proved independently, such as reflexivity and typenarrowing.
Reflexivity. The reflexivity lemma of unified subtyping is defined as follows:
Lemma 6.3.1 (Reflexivity). If Γ ` e1 6 e2 : A, then both Γ ` e1 : A and Γ ` e2 : A hold.
In λI6 , reflexivity is proved by splitting into two sub-lemmas, left and right reflexivity (Lemma
5.3.2 and 5.3.3). Such proof strategy is necessary because right reflexivity has a mutual dependency
on another lemma, correctness of types (Lemma 5.3.11). The mutual dependency is caused bygeneralized top type (see discussion in Section 5.3.1). In λIΣ , such mutual dependency does notexist because top type is an ordinary type but not generalized:
SP-Top

SP-TopRefl

Γ`e:?

`Γ

Γ`e6>:?

Γ`>6>:?

For cases SP-Top and SP-TopRefl, reflexivity can be shown immediately from the induction
hypothesis. Thus, we can prove the reflexivity lemma first without relying on other results.
Weakening, Narrowing and Substitution. The weakening lemma can be proved similarly
as in λI6 by induction on the derivation of Γ1 , Γ3 ` e1 6 e2 : A:
Lemma 6.3.2 (Weakening). If Γ1 , Γ3 ` e1 6 e2 : A and ` Γ1 , Γ2 , Γ3 , then Γ1 , Γ2 , Γ3 ` e1 6 e2 :A.
Due to the absence of bounded quantification, there is no subtyping binding in the context. The
narrowing lemma in λIΣ has just one form, type narrowing:
Lemma 6.3.3 (Type Narrowing). Given Γ1 , x : B , Γ2 ` e1 6 e2 : C , if Γ1 ` A 6 B : ? andΓ1 ` e : A, then Γ1 , x : A, Γ2 ` e1 6 e2 : C .

Chapter 6. Iso-Types with Strong Dependent Sums

108

The proof is by induction on the derivation of Γ1 , x : B , Γ2 ` e1 6 e2 : C . Also notice that thesubtyping of variables in λIΣ is only a reflexive relation (see Section 6.2.3). There is no transitivity
rule for variables, such as S-VarTrans in λI6 . The proof does not rely on the transitivity lemma or
consistency of typing lemma (Lemma 5.3.5), a special case of transitivity. Finally, the substitution
lemma in λIΣ has a different form:
Lemma 6.3.4 (Substitution). If Γ1 , x : B , Γ2 ` e1 6 e2 : A and Γ1 ` v : B , then Γ1 , Γ2 [x 7→v ] ` e1 [x 7→ v ] 6 e2 [x 7→ v ] : A[x 7→ v ].
where the substitute should be a value v, since we treat variables as values and allow reduction ofopen terms, as mentioned in Section 6.2.3. Such form is similar to the one in call-by-value PITS
(see Lemma 4.2.1). The proof relies on transitivity as in λI6 , as well as two additional lemmas,
value substitution and reduction substitution due to value restriction in rules:
Lemma 6.3.5 (Value Substitution).
If v1 and v2 are values, then v1 [x 7→ v2 ] is still a value.
Lemma 6.3.6 (Reduction Substitution).
If v is a value and e1 ,→ e2 holds, then e1 [x 7→ v ] ,→ e2 [x 7→ v ] still holds.
Proofs of two lemmas are straightforward by induction on the structure of v1 and derivationof e1 ,→ e2 , respectively. Note that although the proof of substitution lemma still depends ontransitivity, this is only one-way dependency. Thus, we can similarly show substitution later after
proving transitivity as in λI6 .

6.3.2

Transitivity

The unified subtyping rules in λIΣ do not contain a built-in transitivity rule. We need to prove thetransitivity property. Due to the presence of the subsumption rule (RP-Sub), we need to prove a
generalized transitivity property as in λI6 (see Section 5.3.2). However, we use a slightly different
generalization:
Lemma 6.3.7 (Generalized Transitivity). If Γ ` e1 6 e2 : A and Γ ` e2 6 e3 : B , thenΓ ` e1 6 e3 : B .
which is a rightmost generalization. The difference is the type of the conclusion judgment: we useΓ ` e1 6 e3 : B in λIΣ , while Γ ` e1 6 e3 : A in λI6 which is a leftmost generalization. The
reason is that the typing of the top type (>) is different. In λI6 , the top type is generalized to be
any type by rule S-Top, while it is an ordinary type of kind ? in λIΣ by rule SP-Top:
S-Top

SP-Top

Γ`e:A

Γ`e:?

Γ`e6>:AΓ`e6>:?

Consider the case that e3 = > and we have Γ ` e1 6 e2 : A and Γ ` e2 6 > : B . For thegeneralized top type, we know Γ ` e1 : A by reflexivity from the former judgment. By S-Top,
we obtain the target judgment Γ ` e1 6 > : A, which has the same type as the leftmost term e1 .
For the ordinary top type, we know B = ? by inversion of SP-Top. Note that the target is thesubtyping relation between e1 and >, which requires the type to be ? by SP-Top. It is natural

6.3. Metatheory of λIΣ

109

to set the target as Γ ` e1 6 > : B which uses the rightmost type of >. Otherwise, if we set
the target type to be the leftmost one, i.e., Γ ` e1 6 > : A, we ought to show A = ? which is
unknown to be true. Thus, using rightmost generalized transitivity in λIΣ simplifies the proof forthe case of ordinary top type.
We prove the rightmost generalized transitivity by the same approach used in the leftmost
one (see Section 5.3.2). The proof is by induction on the size of e2 and an inner induction on thederivation of the first judgment Γ ` e1 6 e2 : A. The case for Pi-types (SP-Prod) also needs thetype narrowing lemma (Lemma 6.3.3). Then we can immediately show the original transitivity
lemma which is a direct corollary:
Lemma 6.3.8 (Transitivity). If Γ ` e1 6 e2 : A and Γ ` e2 6 e3 : A, then Γ ` e1 6 e3 : A.

6.3.3

Type Safety

Type-safety of λIΣ is shown by the standard type preservation and progress lemmas [Wrightand Felleisen 1994]. We discuss the design choices of one-step reduction for keeping subtype
preservation and focus on the change of proofs due to the call-by-value semantics used in λIΣ .
Partially Call-by-value. As in λI6 , we need to show a generalized preservation lemma for
the unified subtyping judgment, i.e., subtype preservation:
Lemma 6.3.9 (Subtype Preservation). If Γ ` e1 6 e2 : A, e1 ,→ e10 , e2 ,→ e20 , then Γ ` e10 6 e20 :A.
To ensure that such property holds, we need to restrict the call-by-value semantics to be partial(see Section 6.2.2). We only allow call-by-value semantics for function applications, but callby-name rules for other constructs, e.g., no reduction of sub-terms in casts or dependent sums.
Otherwise, call-by-value rules for casts and dependent sums would break subtype preservation.
We show two counter-examples.
Counter-examples for Full Call-by-value. Assume that we treat cast↑ v as a value and allow
reducing the sub-term in cast↑ by the following rule:
e ,→ e 0
cast↑ e ,→ cast↑ e 0
Let e1 = cast↓ (cast↑ (cast↑ e)) and e2 = cast↓ (cast↑ (cast↑ >)) and assume there exists e 0 suchthat e ,→ e 0 . Note that cast↑ e is reducible and cast↑ > is a value. Relations in the subtype
preservation lemma are as follows:cast↓ (cast↑ (cast↑ e))

6 cast↓ (cast↑ (cast↑ >)),→,→cast↓ (cast↑ (cast↑ e 0 )) 66

cast↑ >The target subtyping relation would not hold because the outer most constructs of both sides aredifferent, i.e., left side is cast↓ left, while right side is cast↑ .

Chapter 6. Iso-Types with Strong Dependent Sums

110

Assume that we treat hv1 , v2 as Σx : A. B i as a value and allow reducing the second
component of a dependent sum by the following rule:
e ,→ e 0
hv , e as Σx : A. B i ,→ hv , e 0 as Σx : A. B i
Let e1 = h?, e as Σx : ?. ?i.1 and e2 = h?, > as Σx : ?. ?i.1 and assume there exists e 0 suchthat e ,→ e 0 . Note that h?, e as Σx : ?. ?i is reducible, while h?, > as Σx : ?. ?i is a value. The
following diagram show the relations in the subtype preservation lemma:h?, e as Σx : ?. ?i.1

6 h?, > as Σx : ?. ?i.1,→,→
h?, e 0 as Σx : ?. ?i.1 66?

Apparently, the target subtyping relation does not hold, since the only subtype of ? is itself.
The Problem of Leftmost Call-by-value. Another unusual design of one-step reduction (,→)
is the adoption of rightmost call-by-value semantics (see Section 6.2.2). In function applications,
we first reduce all arguments to values and then reduce the functions, as indicated by the following
reduction rules:
RP-AppR

RP-AppL

e2 ,→ e20

e ,→ e 0

e1 e2 ,→ e1 e20

e v ,→ e 0 v

Alternatively, one can use the following the leftmost variant of reduction rules that reduce thefunctions first:
e1 ,→ e10

e2 ,→ e20

e1 e2 ,→ e10 e2

v e2 ,→ v e20

The two variants have different impact on the proof of subtype preservation lemma, especiallywhen disproving two diverging cases. Unlike the weak-head call-by-name reduction in λI6 that
only reduces the function part, it is possible in λIΣ that the reduction happens on different
positions within an application and diverges on two sides of a subtyping relation. We need torule out such cases, which would break the subtype preservation.
For the leftmost variant, the diverging cases can be illustrated by the following diagram:e1 e2 6 v e2

,→

,→

,→

,→

e10 e2 6
6
v e20
(1)

v e2 6 e1 e2v e20 66 e10 e2(2)where we assume e1 ,→ e10 and e2 ,→ e20 . Note that e20 6= e2 and subtyping of applications is
pointwise in rules SP-App and SP-AppV. Both targets in (1) and (2) do not hold.
In case (1), the function part e1 on the left-hand side is still reducible, while the right-handside term v e2 only has the reducible argument e2 . Thus, the reduction happens in different places:
the function position on the left-hand side and the argument position on the right-hand side.
Case (2) is simply the mirror of case (1), which exchanges the sides of the subtyping relation.
By inversion of the condition, we know e1 6 v and v 6 e1 from case (1) and (2), respectively.
We can disprove case (1) and (2) by show that e1 is a value which is not reducible:6.3. Metatheory of λIΣ

111Lemma 6.3.10 (Value Preservation).
1. If Γ ` e1 6 e2 : (Πx : A. B ) and e2 is a value, then e1 is also a value.
2. If Γ ` e1 6 e2 : A and e1 is a value, then e2 is also a value.
Thus, both diverging cases are impossible and will not break the subtype preservation lemma.
Notice that the proof depends on several specific rules of λIΣ . The first sub-lemma relies on thefact that T has kind ? by SP-Top. The second sub-lemma relies on the subtyping rule SP-Var
which limits subtyping of variables to be reflexive only. For the first sub-lemma, if we use thegeneralized top type that can have a Pi-type, when e2 = >, e1 can be any well-typed function that
may not be a value. For the second sub-lemma, if bounded quantification is allowed, when e1 = x ,e2 is not necessarily a value but can be any term as long as x 6 e2 : A ∈ Γ. If we want to extend
λIΣ with generalized top type or bounded quantification like λI6 , the value preservation lemma
will not hold and we may not be able to disprove the diverging cases of subtype preservation forthe leftmost variant.
Rightmost Call-by-value to the Rescue. For the rightmost variant, the diverging cases are
simply not possible. If we try to follow the diagram of the leftmost variant, assuming that e1 ,→ e10 ,e2 ,→ e20 , we havee1 v

6 e2 v

e1 v

6 e2 v

,→

6,→

6,→

,→

e10 v

6
6
e2 e
(3)

e1 e

6
6
e20 v
(4)

In (3) and (4), the arguments are already values due to the rightmost reduction strategy. They also
should be the same due to the pointwise subtyping rules. Then, the reduction of the argument
part, i.e., v ,→ e, is contradictory, since values are not reducible.
Thus, the rightmost call-by-value strategy is more suitable for meta-theoretical developmentin λIΣ . It naïvely rules out the diverging cases and simplifies the proof of subtype preservation. It
is also less restrictive and does not rely on the value preservation lemma, which makes it possible
to extend λIΣ with features such as bounded quantification and generalized top type without
breaking subtype preservation.
Determinacy of Reduction. Though the one-step reduction is changed to use the (partially)call-by-value semantics, it still has the same determinacy property as the call-by-name variant inλI6 :Lemma 6.3.11 (Determinacy of Reduction). If e ,→ e1 and e ,→ e2 , then e1 = e2 .
The proof holds few surprises, which is done by induction on the derivation of e ,→ e1 andinversion on e ,→ e2 .
Preservation and Progress. Similarly to λI6 , we prove a generalized subtype preservation
lemma to avoid induction hypothesis issues in the cast↑ case:Lemma 6.3.12 (Generalized Subtype Preservation). Given that Γ ` e1 6 e2 : A holds,

Chapter 6. Iso-Types with Strong Dependent Sums112

1. if A ,→ A0 and both e1 and e2 are cast↑ terms, i.e., e1 = cast↑ e10 and e2 = cast↑ e20 , thenΓ ` e10 6 e20 : A0 ;2. otherwise, if e1 ,→ e10 and e2 ,→ e20 , then Γ ` e10 6 e20 : A.
The first case is slightly changed since we drop the annotation of cast↑ . The proof is by
induction on the derivation of Γ ` e1 6 e2 : A, which is similar to the one of λI6 . The diverging
cases can be trivially disproved due to the choice of rightmost call-by-value reduction. The proof
similarly depends on the “reduction in the middle” lemma, which holds for one-step call-by-value
reduction:
Lemma 6.3.13 (Reduction Exists in the Middle). Given that Γ ` C 6 B : D and Γ ` B 6 A : D,
if C ,→ C 0 and A ,→ A0 , then there exists B 0 such that B ,→ B 0 .
Finally, we can conclude the type preservation lemma, which is simply a corollary of subtype
preservation:
Lemma 6.3.14 (Type Preservation). If Γ ` e : A and e ,→ e 0 , then Γ ` e 0 : A.
We prove the progress lemma that has the judgment with an empty context:
Lemma 6.3.15 (Progress). If ∅ ` e : A then either e is a value v or there exists e 0 such thate ,→ e 0 .
Unlike λI6 , we do not prove a generalized progress lemma (Lemma 5.3.18) since the inert
terms (see Section 5.2.2), which cover all stuck open terms, are not defined for the call-by-value
semantics in λIΣ .

6.4

The Sig Language

We formally present the surface language namely Sig, which supports Scala-like first-class traits
with type members. Sig is a lightweight layer built on top of λIΣ for presenting how iso-strongsums in λIΣ can encode complex constructs such as traits. Expressions of Sig will be elaborated
into λIΣ terms through a type-directed translation. Sig does not expose explicit cast operators.
The translation process will automatically insert necessary casts to keep terms well-typed. In
spite of many language limitations in Sig, the main purpose of Sig is to show the application of
iso-strong sums and the inference of casts via the elaboration semantics. In the rest of this section,
we will show the syntax, static semantics, type-directed translation and translation soundness of
Sig.

6.4.1

SyntaxFigure 6.4 shows the syntax of Sig, which is unified as λIΣ . Terms (E) and types (T ) are in thesame syntactic category. Basic language constructs can be directly mapped to λIΣ terms, e.g.,Type corresponds to ? and the function type corresponds to a Pi-type, etc. We use the syntactic
sugar T1 → T2 for non-dependent function types. Note that there are no explicit type castoperators in Sig.

6.4. The Sig Language
Expressions

Trait Bindings
Object Bindings
Contexts
ValuesSyntactic Sugar

113::= x | Type | (x : T1 ) → T2 | E1 E2 | λ(x : T ) ⇒ E|
trait { type L : T ; S } | obj { type L = E ; M } as T|
x .l | x .L
S::=
val l1 : T1 ; .. ; val ln : Tn
M::=
val l1 = E1 ; .. ; val ln = En∆::=
∅ | ∆, x : T | ∆, x = hx1 , x2 i : T
V::=
Type | x | (x : T1 ) → T2 | λ(x : T ) ⇒ E|
obj { type L = E ; M } as T | x .L
T1 → T2 , (x : T1 ) → T2 where x 6∈ FV(T2 )E, TFigure 6.4. Syntax of Sig
Traits and Objects. A trait has the syntax trait { type L : T ; S } which is a compound typethat has one type member L and multiple value members. The bindings of value members S havethe form val li : Ti , which means the label li has type Ti . Only the type member L but not value
members li can show in Ti . We use the upper-case metavariable L for the label of type member,and the lower-case l for the label of value members. Objects are instances of traits. The syntax
of objects is obj { type L = E ; M } as T where E is the actual type member implementation
for the abstract label L. M is the object bindings with the form val li = Ei where Ei is theimplementation of the member li . Type T after the keyword as is the type annotation. The
member access of objects is denoted by x .L and x .l , which are for the type member and value
member, respectively.
Restrictions on Traits. For simplicity reasons, we have several restrictions related to traits:• There is only one type member in traits, so that traits can be directly mapped to Sigma-typesof λIΣ which have just one binder. Nonetheless, we can simulate multiple type members.
For example, noting that the type T of the type member is polymorphic, which is not
limited to Type, we can specify T as a compound type such as records to represent multiple
type members.
• The member access operations are bound only to variables (e.g. x.L) but not paths (e.g.
x.y.L). This is due to the value restriction in the target language λIΣ . The restriction ofmember access is also commonly used in other calculi for a simpler formalization of traits,
such as Dependent Object Types (DOT) [Rompf and Amin 2016; Amin et al. 2016].
• We do not support subtyping of type members in Sig because there is no bounded quantification in the target language.

6.4.2

Static Semantics

The static semantics of Sig is shown in Figure 6.5 and 6.6. The typing context ∆ has two kindsof bindings, namely the type binding x : T and trait binding x = hx1 , x2 i : T (see Figure 6.4).
Typing rules only use the typing binding. The trait binding is used only for translation and will
be discussed later in Section 6.4.3. The well-formedness of context is checked by the judgment` ∆. Object typing ∆ ` M : S and trait well-formedness ∆ ` S reuse the typing judgment for
inferring the type of object bindings and checking if types of value members are well-formed,
respectively. The typing judgment is denoted by ∆ ` E : T . Typing rules for basic constructs

Chapter 6. Iso-Types with Strong Dependent Sums

114∆`E :T(Term Typing)
ST-Pi

ST-Ax

ST-Var`∆∆ ` Type : Typex :T ∈ ∆`∆∆`x :T∆ ` T1 : Type∆, x : T1 ` T2 : TypeT2 is x.L-only-projection if T1 is a trait∆ ` (x : T1 ) → T2 : Type
ST-AppV∆ ` E : (x : T1 ) → T2
∆ ` V : T1
V is not an object∆ ` E V : T2 [x 7→ V ]ST-App∆ ` E1 : T1 → T2
∆ ` E2 : T1
∆ ` E1 E2 : T2
ST-AppM∆ ` E : (x : T1 ) → T2
∆ ` V1 : T1
T1 = trait { type L : T ; S }V1 = obj { type L = V ; M } as T1∆ ` E V1 : T2 [x .L 7→ V ]ST-Lam∆ ` T1 : Type∆, x : T1 ` E : T2
T2 is x.L-only-projection if T1 is a trait∆ ` (λ(x : T1 ) ⇒ E ) : (x : T1 ) → T2

ST-Mod∆`V :T∆ ` M [L 7→ V ] : S [L 7→ V ]∆ ` T1 : TypeT1 = trait { type L : T ; S }T is not a trait∆ ` obj { type L = V ; M } as T1 : trait { type L : T ; S }ST-Sig∆ ` T : Type∆, L : T ` S
T is not a trait∆ ` trait { type L : T ; S } : Type

ST-ProjT

ST-Proj∆ ` x : trait { type L : T ; S }∆ ` x .L : T∆ ` x : trait { type L : T ; S }val l : T2 ∈ S∆ ` x .l : T2 [L 7→ x .L]

Figure 6.5. Typing rules of Sig
are similar to ones in λIΣ . There is no explicit or implicit type conversion rule. Also, there is no
subtyping relation in Sig and thus no subsumption rule in the typing judgment. In the following
text, we focus on typing rules related to traits.
Applications. Due to the value restriction of the target language, we have multiple application
rules in Sig, namely ST-App, ST-AppV and ST-AppM. Similarly to λIΣ , rules ST-App and STAppV are for non-dependent and dependent function application, respectively. The arguments todependent functions need to be values V (see definitions in Figure 6.4). The case when arguments
are objects is specifically handled by rule ST-AppM. We rule out such case in ST-AppV by requiring
V not to be an object.
Rule ST-AppM checks if the argument V1 is an object and T1 in the function type is a trait
type. The conclusion type is obtained by replacing all type member access x .L in T2 by the actual
type member V . We use a special form of substitution T2 [x .L 7→ V ], called projection substitution.
It pattern-matches the member access form x.L which contains two variables.
Additionally, to ensure the substitution result is well-formed, we need to restrict how x occurs
in T2 , namely if x shows free in T2 , it must be in the form x .L. Then after projection substitution,
we can guarantee that x will not be out of scope in the conclusion type. We formally define such
restriction and call T2 a x.L-only-projection term:
Definition 6.4.1 (Projection-Only Terms). We call E x.L-only-projection if x and L are freevariables in E and x ∈/ FV(E [x .L 7→ y]) for any fresh variable y 6= x.

6.4. The Sig Language

115

`∆

(Context Well-formedness)
SW-Cons
SW-Nil`∆`∅∆ ` T : Type` ∆, x : T∆`M :Sx fresh in ∆(Object Typing)
SM-Bind∆ ` Ei : Tiii

∆ ` val li = Ei : val li : Ti

i∆`S

(Trait Well-formedness)
SG-Sig∆ ` Ti : Type∆ ` val li : Tiii

Figure 6.6. Other rules of Sig
We check if T2 satisfies such restriction when the argument type T1 is a trait in rules ST-Lam
and ST-Pi, i.e., rules for type-checking functions and function types.
Handling the object case separately and using projection substitution in ST-AppM is due
to value restrictions on member access and lack of explicit or implicit type conversion in Sig.
Otherwise, consider using ST-AppV for the object case. Since only member access on variables is
supported, after substitution, all x .L in T2 will become V1 .L which is not well-formed. Furthermore, there is no type conversion to transform V1 .L into V . We directly replace all x .L with V ,without the need of an individual type conversion rule or operator.
Objects and Traits. Objects and traits are type-checked by ST-Mod and ST-Sig, respectively.
The actual type member V is limited to a value. The reason is that an object will be mapped to adependent sum in λIΣ and the actual type member corresponds to the first component, whichis required to be a value (see SP-Pair). The type of object bindings M is obtained by replacing
all abstract type member L with the actual one V . And we use the trait binding S from theannotation T1 to check if the type of M is S [L 7→ V ]. We also require T , the type of V , not to
be a trait. Otherwise, there could exists the form L.li in object bindings M . Then M [L 7→ V ]contains V .li , which is an ill-formed member access. Correspondingly, in the typing rule of traits
ST-Sig, the type T of abstract type member L should not be a trait.
Member Access. ST-ProjT and ST-Proj are typing rules for type and value member access,respectively. For a certain value member l, its type T2 is extracted from S by its label and may
contain the abstract type member L. We replace all L in T2 with member access x.L to prevent L
being out of scope. Sig only supports object member access of variables. Because member accesswill be translated to projection and opening operations in λIΣ . Both projection and opening havevalue restrictions which only take values as input. Variables are values both in λIΣ and Sig,

Chapter 6. Iso-Types with Strong Dependent Sums

116

which satisfies the restriction. Member access on other values, such as objects is not allowed.
Otherwise, type conversion will be needed. If V.l is allowed in ST-Proj where V is an object,
its type would be T2 [x 7→ V.L] which needs to further convert the type V.L to the actual typemember.
No Subsumption Rule or Subtyping Relation. Finally, for simplicity reasons, we exclude
the subsumption rule and subtyping relation in Sig. The subsumption rule would make thesystem declarative and harden the development of metatheory. Moreover, we focus on presenting
the typing of Sig, as well as the type-directed elaboration which involves the inferences of casts(see Section 6.4.3). The elaboration of subtyping is less interesting because subtyping relations
between traits can be directly mapped to record subtyping in λIΣ . We leave adding subtyping in
Sig as future work (see Section 8.2).

6.4.3

Elaboration Semantics

The semantics of Sig is given by elaboration to λIΣ . The elaboration is a type-directed translationof the surface language Sig to the target language. For simplicity reasons, we assume the target
language is λIΣ extended with multi-field records. Records can be encoded using top types withstandard techniques [Pierce 2002]. Typing and subtyping rules of records are admissible in λIΣ .
The main purpose of presenting the elaboration semantics is to illustrate how necessary
type-safe casts can be automatically added to target terms. The translation process of Sig isparticularly for the inference of casts with traits and objects. For encoding other constructs
with casts, we may need different elaboration approaches. For example, in Section 3.2.1 we use
Scott-encodings for elaborating algebraic datatypes of Fun into PITS terms with casts.
The judgment for term translation is denoted by ∆ ` E : Te, shown in Figure 6.7 and 6.8.
If we ignore the target term e and trait binding x = hx1 , x2 i : T in ∆, the translation judgment
becomes exactly the typing judgment ∆ ` E : T (see Figure 6.5). Most translation rules are
straightforward mappings to λIΣ terms. We distinguish the translation for terms with or without
objects/traits. The name of rules related to traits has a suffix letter “M”. We focus on such rules in
the following text.
Other translation judgments are shown in Figure 6.9, which reuse the term translation judgment. The context translation judgment ` ∆Γ translates a surface context to a target one.
In rule TRW-Mod, the trait binding x = hx1 , x2 i : T is used to save the translation result of an
object variable x. We decompose x as fresh variables x1 and x2 , which represent the first andsecond components of a dependent sum translated from an object. The object and trait bindingtranslation judgments, i.e., ∆ ` M : Se and ∆ ` Se, translate bindings in objects andtraits to records and record types, respectively.
Object Variables. Rule TR-VarM in Figure 6.7 translates a variable x when it is a trait bindingx = hx1 , x2 i : T from the context. Its type T is a trait and translated into a Sigma-type Σx1 : A. B .
The object variable x is then translated to a dependent sum hx1 , x2 as Σx1 : A. B i. Note that x
does not show in the translated term. One can only refer to x by its component variables x1 or
x2 , which are both already in the translated context by TRW-Mod. This rule follows the form of
the translation of object definitions in rule TR-Mod. Thus, we can translate an object value V ina unified form ∆ ` V : T
he1 , e2 as Σx : A. B i.

6.4. The Sig Language∆`E :T

117(Term Translation)e
TR-VarM

TR-Ax

TR-Var`∆Γ∆ ` Type : Typex :T ∈ ∆`∆∆`x :Tx?

Γx = hx1 , x2 i : T ∈ ∆`∆Γ∆ ` T : TypeΣx1 : A. B∆`x :T
hx1 , x2 as Σx1 : A. B i

TR-Pi∆ ` T1 : Type∆, x : T1 ` T2 : TypeA2∆ ` (x : T1 ) → T2 : TypeA1
T1 is not a trait
Πx : A1 . A2

TR-Lam∆ ` T1 : TypeA∆, x : T1 ` E : T2e
T1 is not a trait∆ ` (λ(x : T1 ) ⇒ E ) : (x : T1 ) → T2
λx : A. e
TR-PiM∆ ` T1 : TypeΣx1 : A. B∆, x = hx1 , x2 i : T1 ` T2 : TypeC
T1 = trait { type L : T ; S }T2 is x.L-only-projection∆ ` (x : T1 ) → T2 : TypeΠy : (Σx1 : A. B ). (λx1 : A. C ) (y.1)
TR-LamM∆ ` T1 : TypeΣx1 : A. B∆, x = hx1 , x2 i : T1 ` E : T2e
T1 = trait { type L : T ; S }T2 is x.L-only-projection∆ ` (λ(x : T1 ) ⇒ E ) : (x : T1 ) → T2
λy : (Σx1 : A. B ). open y as hx1 , x2 i in e

Figure 6.7. Translation of terms
Functions with Traits. Rules TR-PiM and TR-LamM in Figure 6.7 translate function types
and functions where the argument type T1 is a trait. The trait T1 is translated to a Sigma-type
Σx1 : A. B . The formal parameter x is added into the context as a trait binding x = hx1 , x2 i : T1
correspondingly. Recall that in TR-VarM and TRW-Mod, x does not exist in the translated context
and can only be referred by component variables x1 or x2 . In TR-LamM, the function body E
will be translated to e. The member access operations in E will be directly mapped to operations
on component variables in e (see TR-ProjT and TR-Proj). Such behavior can be mapped to the
opening operation in λIΣ , which replaces the input variable x with two pattern variables x1 andx2 . The whole function λ(x : T1 ) ⇒ E is then translated into a lambda term with opening. We
explicitly replace x with a fresh variable y in the translated term to distinguish from x1 and x2 .
Rule TR-PiM matches the type of the translated term in TR-LamM. The whole translated type is a
Pi-type, parametrized by the fresh variable y. The body is exactly the type of the open-term in
TR-LamM, which follows SP-Open of the target language.
Applications with Traits. Functions with traits as input are translated to lambdas with openterms in TR-LamM separately from ordinary functions. Thus, applications with such functions alsoneed a special treatment. Rules TR-AppX and TR-AppM in Figure 6.8 translate dependent functions
applied to object values, which cover two cases: variables x or obj definitions, respectively.

Chapter 6. Iso-Types with Strong Dependent Sums

118∆`E :T(Term Translation)e

TR-App

TR-AppV∆ ` E1 : T1 → T2
e1
∆ ` E2 : T1
e2
T1 is not a trait∆ ` E1 E2 : T2e1 e2

∆ ` E : (x : T1 ) → T2e1
∆ ` V : T1
e2
T1 is not a trait∆ ` E V : T2 [x 7→ V ]e1 e2

TR-AppX∆ ` E : (x : T1 ) → T2e
∆ ` y : T1
hy1 , y2 as Σx1 : A. B i
T1 = trait { type L : T ; S }∆ ` E y : T2 [x 7→ y]

cast2↓ (e hy1 , y2 as Σx1 : A. B i)

TR-AppM∆ ` E : (x : T1 ) → T2e
∆ ` V1 : T1
he1 , e2 as Σx1 : A. B i
T1 = trait { type L : T ; S }V1 = obj { type L = V ; M } as T1∆ ` E V1 : T2 [x .L 7→ V ]cast2↓ (e he1 , e2 as Σx1 : A. B i)

TR-Mod∆`V :Te1∆ ` M [L 7→ V ] : S [L 7→ V ]e2∆ ` T1 : TypeΣx1 : A. B
T1 = trait { type L : T ; S }T is not a trait∆ ` obj { type L = V ; M } as T1 : trait { type L : T ; S }he1 , e2 as Σx1 : A. B i
TR-Sig

TR-ProjT∆ ` T : TypeA∆, L : T ` S
B
T is not a trait∆ ` trait { type L : T ; S } : TypeΣx1 : A. B [L 7→ x1 ]∆ ` x : T1
hx1 , x2 as Σx1 : A. B i
T1 = trait { type L : T ; S }∆ ` x .L : T
x1

TR-Proj∆ ` x : T1
hx1 , x2 as Σx1 : A. B i
T1 = trait { type L : T ; S }val l : T2 ∈ S∆ ` x .l : T2 [L 7→ x .L]
x2 .l

Figure 6.8. Translation of terms (cont.)

Note that the type of a translated trait function, i.e., a open-term, is a type-level application(λx1 : A. C ) (y.1) in TR-PiM. We need two consecutive cast↓ s in the target term to reduce
the first projection and lambda application, similarly to the treatment of second projections(see Section 6.2.3). The function part E is translated to e by TR-LamM. The argument part istranslated to a dependent sum. In TR-AppX, the object variable is translated to a dependent sum
with component variables by TR-VarM. In TR-AppM, the object definition V1 is translated to adependent sum by TR-Mod.
Other Translations with Traits. TR-Mod translates an object definition into a dependentsum. The actual type member V is mapped to the first component e1 . The object bindings
M are mapped to the second component e2 , which is a record by object binding translation∆`M :Se. The members in M have the same labels as in e1 , which can be extracted
directly by record projections. TR-Sig translates a trait into a Sigma-type. The type of abstract
type member T is translated to the binder type A. The trait binding S is translated to a record

6.4. The Sig Language`∆(Context Translation)

ΓTRW-Cons

TRW-Mod`∆Γ∆ ` T : TypeA
x fresh in ∆` ∆, x : T
Γ, x : A`∆

TRW-Nil

`∅

119

∅

∆`M :SΓ∆ ` T : TypeΣx1 : A. B
x fresh in ∆x1 , x2 fresh in Γ` ∆, x = hx1 , x2 i : T
Γ, x1 : A, x2 : B(Object Binding Translation)e
TRM-Bind∆ ` Ei : Tiiei

∆ ` val li = Ei : val li : Ti

∆`S

i

i

i

{ li = ei }(Trait Binding Translation)e
TRS-Sig∆ ` Ti : Type∆ ` val li : Ti

i

Ai

i
i

{ li : Ai }Figure 6.9. Translation of contexts and bindings
type B by trait binding translation ∆ ` S
e. The type and value member access operations aretranslated by TR-ProjT and TR-Proj, respectively. Type member access is directly mapped to thefirst component. Value member access is mapped to record projection of the second component.

6.4.4

Soundness of Translation

We show that the type-direct translation of Sig is sound, i.e., the translated target terms are
well-typed. The main lemma is stated as follows:
Lemma 6.4.1 (Soundness of Translation .).
Given ` ∆Γ, if ∆ ` E : T

e and ∆ ` T : TypeA, then Γ ` e : A.

The proof is straightforward by induction on the derivation of the term translation judgment∆`E :Te.
Substitution Lemmas. The soundness proof depends on special substitution lemmas. As
mentioned in Section 6.4.2, rule ST-AppM involves the projection substitution with form T2 [x .L 7→
V ] that replaces a type member access with a value. Also, value substitution such as E [x 7→ V ]for an arbitrary term E may fail since E may contain member access operations x .L and x .l ,which are only for variables and become malformed after substitution with V . If terms do nothave member access on variables to substitute, the terms should keep well-formedness after
substitution. We define such terms formally as non-projection terms:
Definition 6.4.2 (Non-projection Terms). We call E x-non-projection if it does not contain any
projection form of x (i.e. x .L or x .l where x occurs free in E ). Similarly, bindings ∆, M and S are
x-non-projection if they only contain x-non-projection terms.

120

Chapter 6. Iso-Types with Strong Dependent Sums

It is easy to see that all sub-terms of a x-non-projection term are still x-non-projection. Thus, asubstitution “x 7→ V ” on x-non-projection terms is safe. We can show the following value, typing
and projection substitution lemmas:
Lemma 6.4.2 (Value Substitution .). If V1 is a x-non-projection value and V2 is a value, thenV1 [x 7→ V2 ] is still a value.
Lemma 6.4.3 (Typing Substitution .). If ∆1 , z : T1 , ∆2 ` E : T
e and ∆1 ` V2 : T1v,
where E and ∆2 are z-non-projection, then ∆1 , ∆2 [z 7→ V2 ] ` E [z 7→ V2 ] : T [z 7→ V2 ]e[z 7→ v ].
Lemma 6.4.4 (Projection Substitution .). Given T 0 = trait { type L1 : T3 ; S1 }, if ∆1 , z =hz1 , z2 i : T 0 , ∆2 ` E : T
e and ∆1 ` V2 : T3
v , where E and ∆2 are z.L1 -only-projection,then ∆1 , ∆2 [z .L1 7→ V2 ] ` E [z .L1 7→ V2 ] : T [z .L1 7→ V2 ]e[z1 7→ v ].
Proofs are straightforward by induction. Notice that for value substitution lemma, when V1 isa type member access, it cannot be x .L since it is x-non-projection. Thus, V1 = y.L for somey 6= x, then V1 [x 7→ V2 ] = V1 = y.L is still a value.

121

CHAPTER

7

Related Work

7.1

Dependently Typed Calculi without Subtyping

7.1.1

Core Calculus for Functional Languages

Girard’s System Fω [Girard 1972] is a typed lambda calculus with higher-kinded polymorphism.
For the well-formedness of type expressions, an extra level of kinds is added to the system. In
comparison, because of unified syntax, PITS is considerably simpler than System Fω , both in termsof language constructs and complexity of proofs. As for type-level computation, System Fω differsfrom PITS in that it uses a conversion rule, while PITS uses explicit casts. PITS is also inspiredby the treatment of datatype constructors in Haskell [Jones 1993]. Iso-types have similarities
to newtypes and datatypes which involve explicit type-level computations. The current corelanguage for GHC Haskell, System FC [Sulzmann et al. 2007] is a significant extension of System
F , which supports GADTs [Peyton Jones et al. 2004], functional dependencies [Jones 2000], typefamilies [Eisenberg et al. 2014], and kind equality [Weirich et al. 2013]. System DC [Weirich
et al. 2017] is a further extension to FC and foundation of Dependently Typed Haskell (DTH)that extends Haskell with full-spectrum dependent types. System FC and its extensions require a
non-trivial form of type equality, which is currently missing from PITS. One possible direction
for future work is to investigate the addition of such forms of non-trivial type-equality. On theother hand, PITS uses unified syntax and has only 8 language constructs, whereas the original
System FC uses multiple levels of syntax and currently has over 30 language constructs, making
it significantly more complex. The simplicity of PITS makes it suitable to be combined with otherlanguage features, such as subtyping and strong sums, which seem hard to support in FC and
its extensions. For example, we have presented the λI6 calculus that extends a variant of PITS
(i.e. λI) with subtyping in Chapter 5, and the λIΣ calculus which is a variant of λI6 with strongsums in Chapter 6.

7.1.2

Unified Syntax with Decidable Type-checking

Pure Type Systems [Barendregt 1991] show how a whole family of type systems can be implemented using just a single syntactic form. PTSs are an obvious source of inspiration for ourwork. An early attempt of using a PTS-like syntax for an intermediate language for functional
programming was Henk [Peyton Jones and Meijer 1997]. The Henk proposal was to use thelambda cube as a typed intermediate language, unifying all three levels, i.e., terms, types andChapter 7. Related Work122

kinds. However the authors have not studied the addition of general recursion, full dependent
types or the meta-theory.
Zombie [Casinghino et al. 2014] is a dependently typed language using a single syntactic
category. It is composed of two fragments: a logical fragment where every expression is known
to terminate, and a programmatic fragment that allows general recursion. Though Zombie has
one syntactic category, it is still fairly complicated (with around 24 language constructs) as it tries
to be both consistent as a logic and pragmatic as a programming language. Even if one is onlyinterested in modeling a programmatic fragment, additional mechanisms are required to ensure
the validity of proofs [Sjöberg et al. 2012; Sjöberg and Weirich 2015]. In contrast to Zombie, PITS
takes another point of the design space, giving up logical consistency and reasoning about proofs
for simplicity in the language design.

7.1.3

Unified Syntax with General Recursion and Undecidable Type Checking

Cayenne [Augustsson 1998] integrates the full power of dependent types with general recursion,
which bears some similarities with PITS. It uses one syntactic form for both terms and types,
allows arbitrary computation at type level and is logically inconsistent because of the presenceof unrestricted recursion. However, the most crucial difference from PITS is that type checking
in Cayenne is undecidable. From a pragmatic point of view, this design choice simplifies theimplementation, but the desirable property of decidable type checking is lost. Cardelli’s Type:Type
language [Cardelli 1986b] also features general recursion to implement equi-recursive types.
Recursion and recursive types are unified in a single construct. However, both equi-recursive
types and the Type:Type axiom make the type system undecidable. ΠΣ [Altenkirch et al. 2010] is
another example of a language that uses one recursion mechanism for both types and functions.
The type-level recursion is controlled by lifted types and boxes since definitions are not unfolded
inside boxes. However, ΠΣ does not have decidable type checking due to the “type-in-type”
axiom, and its metatheory is not formally developed.

7.1.4

Casts for Managed Type-level Computation

Type-level computation in PITS is controlled by explicit casts. Several studies [Stump et al. 2008;
Sjöberg et al. 2012; Kimmell et al. 2012; Sjöberg and Weirich 2015; Sulzmann et al. 2007; Gundry
2013; Weirich et al. 2017] also attempt to use explicit casts for managed type-level computation.
However, casts in those approaches are not inspired by iso-recursive types. Instead they require
equality proof terms, while casts in PITS do not. The need for equality proof terms complicates thelanguage design because: 1) building equality proofs requires various other language constructs,
adding to the complexity of the language design and metatheory; 2) It is desirable to ensure thatthe equality proofs are valid. Otherwise, one can easily build bogus equality proofs with nontermination, which could endanger type safety. Guru [Stump et al. 2008] and Sep3 [Kimmell et al.
2012] make syntactic separation between proofs and programs to prevent certain programmatic
terms turning into invalid proofs. System DC [Weirich et al. 2017] and other FC variants [Sulzmann
et al. 2007; Yorgey et al. 2012] similarly distinguish coercions (i.e. equality proofs) and programs
syntactically. The programmatic part of Zombie [Sjöberg et al. 2012; Sjöberg and Weirich 2015],
which has no such separation, employs a value restriction that restricts proofs to be syntactic
values to avoid non-terminating terms. Gundry’s evidence language [Gundry 2013] also unifies all
syntactic levels including coercions, but uses different phases for separating programs and proofs.

7.2. Calculi with Subtyping and Dependent Types123

Table 7.1. Comparison between λI6 and related calculi
Features
Dependent types
Beta equality
Unified syntax
Contravariance
Bounded quantification
Top type
Transitivity not rely on normalization
1
2

λI6
#

F6
#
#
#

PTS6

#
G1
#

PSS

#
—2

No subtyping relation for lambdas with bounded quantification.
Metatheory not fully developed.

λP6

λΠ6

#

#

#
#
#

#
#
#

λC6

#
#

The typing rules contain an access policy relation to determine the conversion of phases. Suchmechanism is finer-grained yet more complicated. Note that our treatment of full casts in full
PITS, using a separate erased system for developing metatheory, is similar to the approach of
Zombie or Guru which uses an unannotated system.

7.1.5

Restricted Recursion with Termination Checking

As proof assistants, dependently typed languages such as Coq [The Coq development team 2016]
and Agda [Norell 2007b] are conservative as to what kind of computation is allowed. They require
all programs to terminate by means of a termination checker, ensuring that recursive calls are
decreasing. Decidable type checking and logical consistency are preserved. But the conservative,
syntactic criteria is insufficient to support a variety of important programming styles. Agda
offers an option to disable the termination checker to allow writing arbitrary functions. However,this may endanger both decidable type checking and logical consistency. Idris [Brady 2011] isa dependently typed language that allows writing unrestricted functions. However, to achieve
decidable type checking, it also requires termination checker to ensure only terminating functions
are evaluated by the type checker. While logical consistency is an appealing property, it is not agoal of PITS. Instead PITS aims at retaining (term-level) general recursion as found in languages
like Haskell or ML, while benefiting from a unified syntax to simplify the implementation and themeta-theory of the core language.

7.2

Calculi with Subtyping and Dependent Types

In this section, we discuss several related calculi that support subtyping and dependent types(except System F6ω and F··ω ). The comparison of features between several closely related calculi
and λI6 is summarized in Table 7.1. One quick observation from the table is that only λI6 cansupport all language features of F6 , while other calculi cannot fully subsume F6 .

7.2.1

Subtyping with Unified Syntax

It is appealing to combine subtyping with the unified syntax of Pure Type Systems [Barendregt
1991] (PTS) for obtaining a concise and expressive system. Chen proposed λC6 [Chen 1997], an
extension of the calculus of constructions (λC) with subtyping. λC6 supports neither top types
nor bounded quantification in order to simplify the metatheory. The proof of transitivity in λC6
is simpler and does not depend on strong normalization, though decidability still depends on

Chapter 7. Related Work124

strong normalization as in λC. Zwanenburg proposed PTS 6 [Zwanenburg 1999] by extending
PTS with subtyping and bounded quantification. It has the PTS-style unified syntax but with two
distinct forms of abstraction for type and bound. In PTS 6 , the subtyping rules do not depend on
the typing rules, which allows proving subtyping properties independently from typing properties.
However, such design makes it difficult to extend the framework with two desirable features:
1) subtyping on bounded abstractions, since subtyping rules are defined only for pre-terms; 2)
top types, since the subtyping rule of top types depends on typing. Neither of those features aresupported by PTS 6 .
Hutchins proposed another framework called Pure Subtype Systems [Hutchins 2010] (PSS)
which also adopts the unified syntax based on PTS. The design is simplified by making the systemsolely based on subtyping without the typing relation. The simplicity of the system comes atthe cost of the complexity of metatheory. The proof of transitivity elimination is partial, andtherefore subject reduction cannot be proved. Note that although λI6 shares the similar idea ofbeing based on the subtyping relation, it has two major differences from PSS. First, λI6 unifies
subtyping with typing in a more conservative way. The unified subtyping relation still tracks
types and it intuitively subsumes the traditional typing relation. In contrast, PSS takes a moreaggressive approach to make the typing relation completely absent from the system. In PSS there
are no types or typing. Second, PSS eliminates the distinction of function and function types,
which are unified into the same syntax of abstraction. In contrast, λI6 still distinguishes thesetwo concepts as in PTSs. Since the subtyping rule of abstractions in PSS is pointwise, any form ofcontravariance is not supported. An unfortunate consequence is that PSS cannot subsume System
F6 with contravariant arrow types, including the Kernel Fun variant [Cardelli and Wegner 1985].

7.2.2

Stratified Syntax with High-Order Subtyping

System F6ω is a lambda calculus with stratified syntax by extending System Fω [Girard 1972] withhigher-order subtyping. To simplify the metatheory, early formalizations of System F6ω [Pierce
and Steffen 1997; Compagnoni 1995] do not allow a bounded type operator. Compagnoni and
Goguen later proposed a technique called typed operational semantics [Compagnoni and Goguen
2003] to fully enable bounded quantification in System F6ω . But its metatheory becomes quite
complicated and relies on strong normalization, making it hard to apply such technique to systems
with general recursion. Note that Compagnoni and Goguen’s presentation of System F6ω contains
a kinded subtyping judgment Γ ` A 6 B : K which has a similar shape to the unified subtyping
relation in λI6 . But the typing relation is separately defined in their system and not subsumed by
the kinded subtyping judgment. System F··ω [Stucki 2017] is an extension of F6ω with type intervals.
F··ω supports higher-order subtyping with both lower and upper bounded quantifications but its
metatheory is complex due to the stratified syntax. The canonical/algorithmic system of F··ω relies
on normalization. The transitivity rule cannot be fully eliminated but partially eliminated for
top-level uses.

7.2.3

Stratified Subtyping Systems with Dependent Types

System λP6 [Aspinall and Compagnoni 1996] is a stratified system with dependent types andhigher-order subtyping. The metatheory becomes more complex than System F6ω due to thecircular dependency of typing, kinding and subtyping. A novel proof technique that splits beta
reduction on terms and types is proposed to break such dependency. However, System λP6 does

7.3. Strong Sum Types and ML Modules

125

not support polymorphism (i.e. abstraction over types), bounded quantification or top types.
System λΠ6 [Castagna and Chen 2001; Chen 1998] is an improvement of λP6 . It has the property
of complete type-level transitivity elimination, while System λP6 has transitivity elimination only
for normalized types. However, λΠ6 is proved to be equivalent to λP6 in typing and subtyping,meaning that it has no increased expressiveness. Both λΠ6 and λP6 require strong normalization
to prove the transitivity of subtyping. In contrast, λI6 employs iso-types for explicit type-levelcomputations and decouples strong normalization from the proofs of metatheory.

7.2.4

Subtyping with Restricted Dependent Types

There have been several studies focusing on exploring subtyping with restricted forms of dependent
types but not full dependent types in the context of object-oriented (OO) programming. The
Dependent Object-Oriented Language [Campos and Vasconcelos 2015, 2018] (DOL) is an imperative
OO programming language with subtyping and index refinements, a restricted notion of dependent
types originated from Dependent ML [Xi and Pfenning 1999], which allows types to dependon static indices of natural numbers. DOL supports the verification of mutable objects andunrestricted use of shared objects. The type checking of DOL is decidable. Compared to λI6 ,DOL does not support full dependent types or general bounded quantification. In DOL, Pi-types
are denoted by Πa : I.T and can be quantified only by index types I. Quantifiers in Pi-types only
support propositions on indexes, such as comparing natural numbers a 6 b.
νObj [Odersky et al. 2003] is a dependently typed calculus for objects with type members.
It is developed as a theoretic foundation for Scala [Odersky et al. 2004] and features a weaker
form of dependent types called path-dependent types. In νObj , types can depend on paths which
are type selections on variables, i.e., x.L. Compared to traditional dependent types used in
λI6 , it is difficult to use path-dependent types to model dependency on non-path values, e.g.,Πn : Int. Vec n. The richness of the type system makes the metatheory of νObj complex andtype checking is not decidable. Another recent effort of developing a core calculus for Scala is the
Dependent Object Types (DOT) calculus [Amin et al. 2012b, 2014; Rompf and Amin 2016; Amin et al.
2016]. DOT is also based on path-dependent types. It is simpler and has fewer type forms thanνObj , e.g., no class types, but still expressive to model many features of Scala. Similarly to λI6 ,DOT subsumes System F6 but has a richer notion of bounds. Type variables can be quantified byboth lower bounds and upper bounds, as opposed to the traditional bounded quantification usedin λI6 that only supports upper bounds. The metatheory of DOT is well-developed [Rompf andAmin 2016], though the soundness proof requires many non-standard techniques. Transitivity of
subtyping needs to be treated as an axiom and transitivity elimination is not possible [Rompf andAmin 2016]. Both νObj and DOT use the stratified syntax in contrast to the unified syntax of
λI6 .

7.3

Strong Sum Types and ML Modules

7.3.1

Dependently Typed Calculi with Strong Sigma-types

It is challenging to combine strong dependent sums with traditional dependently typed systems. If
both impredicative polymorphism and strong sums are allowed, Girard’s paradox can be derived
and logical consistency is lost [Coquand 1986; Hook and Howe 1986]. Previous studies usually
drop impredicativity to obtain a consistent system with strong sums. XML [Harper and Mitchell

Chapter 7. Related Work126

1993] extends Standard ML with a module system encoded by strong dependent sums. XML
uses implicit type conversions by equality relations and utilizes stratified universes to abandon
impredicative polymorphism.
Instead of completely dropping impredicativity, another feasible approach [Harper and
Mitchell 1993] is to limit predicativity only in strong Sigma-types and allow impredicativity
in Pi-types. However, such predicative Sigma-types are more restricted and less expressive, sinceboth the binder type and body should be at the same small kind level, i.e., for Σx : A. B , both
A : ? and B : ? are required. For example, Σx : ?. x is not predicative with stratified universes
where ? : 2. The Calculus of Dependent Lambda Eliminations (CDLE) [Stump 2017] supports
impredicativity and encoding strong sums without treating them as built-in constructs, though theencoded Sigma-types are predicative. Bowman et al. [2017] proposed an extension of the Calculusof Constructions with strong dependent sums for type-preserving CPS translation. Similarly, intheir system Pi-types are impredicative but strong sum types are predicative so as to prevent theinconsistency issue.
The λIΣ calculus supports impredicativity both in Pi-types and strong Sigma-types by using
a single unified universe (i.e. ?) and the “type-in-type” axiom. Thus, the calculus is logicallyinconsistent. Nonetheless, we do not consider inconsistency problematic for λIΣ . We focus moreon the traditional programming patterns, while the related studies mentioned above mostly focus
on logical uses such as proof assistant. The loss of strong normalization does not cause problems
either, since iso-types untangles normalization from other properties of λIΣ .

7.3.2

Strong Sigma-types with Subtyping

It is even more challenging to allow subtyping with Sigma-types. There is not so much existing
work due to the complexity of combining subtyping and dependent sum types. On exception is
the work by Luo et al. [2004] on coherent subtyping rules of strong Sigma-types. They propose
a new subtyping rule for the first projection of Sigma-types and achieve both coherence andadmissibility of transitivity. Their system only supports predicative strong sums, similarly to thecalculi by Stump [2017] and Bowman et al. [2017]. Several other work, such as dependent records
by Pollack [2002], is based on Luo et al.’s rules. One fundamental difference is that they use coercive
subtyping, while we use structural subtyping based on the approach of unified subtyping [Yangand Oliveira 2017]. Coercive subtyping allows more flexible subtyping rules in their system,
however also requires the additional relation, i.e., coercion, and needs to ensure its coherence.
The unified subtyping approach used in λIΣ directly reasons on the structures of types.

7.3.3

Core Languages for Scala

As shown in the surface language Sig, dependent sums in λIΣ can model several Object-oriented
Programming (OOP) structures in Scala [Odersky et al. 2004], e.g., traits and type members.
There are several calculi which aim to serve as theoretical foundations of Scala as mentioned in
Section 5.6, including νObj [Odersky et al. 2003] and Dependent Object Types (DOT) calculus [Aminet al. 2012b, 2014; Rompf and Amin 2016; Amin et al. 2016]. The key feature is path-dependent
types for modeling member access of traits. νObj supports full paths p.L, while DOT supports
short paths on variables only, i.e., x.L, similarly to the restriction in Sig. Both calculi can model
more complete Scala features, including both lower and upper bounds for type members, which is
missing in λIΣ . Nonetheless, λIΣ is not intended for modeling full Scala features, though it can7.3. Strong Sum Types and ML Modules

127

support some features of type members as shown in Sig. Traditional full dependent types, suchas Πn : Int. Vec n, are not expressible in νObj or DOT. Higher-kinded types are not currently
available in DOT but supported by F··ω [Stucki 2017], a Fω variant of DOT with upper and lower
bounds but without type members or path-dependent types. λIΣ supports both dependent types
and high-kinded types. Both transitivity elimination and type-safety are proved for λIΣ . In
contrast, νObj does not have fully-developed metatheory. DOT has a relatively more complex
soundness proof [Rompf and Amin 2016; Rapoport et al. 2017]. DOT needs a built-in transitivity
rule and does not support transitivity elimination.

7.3.4

Encoding ML Modules by Dependent Types

Dependent sums are the key novelty of λIΣ over λI6 . Besides OOP language constructs, dependentsums can also model ML-like model systems. MacQueen [1986] proposed such an idea to model
functors and signatures using dependent types and strong existential types, i.e., strong sum types.
Several other work also tries to encode modules with strong sums, e.g., XML by Harper and
Mitchell [1993], as well as Leroy’s calculus that employs both strong sums and weak manifest
sums [Leroy 1994]. For a proper module system, one needs the strong existential opening andsecond projection from strong sums, because traditional existential opening is too restrictive. It
does not allow free access to the witness and interpretation components of an existential package.
Notice that all these previous studies use an implicit conversion rule with equality judgments,
while λIΣ employs the iso-type approach with explicit type casts. Instead of using the standard
typing rule for the second projection, in λIΣ , we slightly weaken the typing rule of the second
projection and strong opening to make them compatible with call-by-value casts. Alternatively,
strong sums can be typed using full casts with parallel reduction. But the cost is the complexityof metatheory and the difficulty to combine with other features, such as subtyping.

7.3.5

Encoding ML Modules by F-ing Modules

Instead of directly using dependent sums, ML module systems can be encoded through indirectsemantics by second-order type systems and ordinary existential types. Rossberg et al. [2010]
proposed F-ing modules which elaborate ML modules into System Fω . The target language does
not need dependent types or dependent sums. But such encoding requires a complex elaboration
process. The semantics of modules is indirect, which is represented differently in the surface andtarget language. For example, an abstract signature is an existential type ∃α.Σ in the surface
ML language that binds abstract types α. It will be instantiated into a concrete signature Σ in Fω
which is a record type. Thus, member access of a module can be done internally in an existential
package, because the semantics signature is “virtual”, i.e., an existential package with abstract
binders. There is no actual existential opening and thus the encoding does not require strong
existentials, i.e., strong dependent sums.
Type members and traits encoded in Sig share some similarities to ML-like modules: traits
are like signatures and objects are like structures. We use a type-directed translation from Sig
to λIΣ , similarly to the elaboration used in F-ing modules. However, our translation process ismuch simpler. The surface structures of Sig have direct mappings in the target language. Withdependent sums, we can directly use existential openings. Note that the opening operation inλIΣ has an intermediate type which is a type-level application. The actual type is delayed until
the actual implementation is provided, and then can be obtained by cast↓ s. This is similar to theChapter 7. Related Work128

treatment of obtaining concrete signatures in F-ing modules. However, λIΣ uses dependent types
and does not need “virtual” signatures that always carry existential binders.

7.3.6

First-class ML Modules

Traditionally, ML modules are treated as a separate system from the core language. Modules
cannot be freely mixed with terms. 1ML [Rossberg 2015] is such an attempt to unify the coreand modules, which features F-ing modules to elaborate both predicative ML core and module
systems into a well-studied target language, i.e., System Fω . Another earlier work by Harperand Lillibridge is translucent sums [Harper and Lillibridge 1994; Lillibridge 1997] that support
transparent type definitions (i.e. type L = T ) in signatures. Modules encoded by translucent sums
are first-class values. Essentially, translucent sums are weak sums extended with type equality.
Similarly to 1ML, Harper and Lillibridge’s calculus is based on System Fω but not a dependent
type theory.
Thanks to unified syntax in λIΣ , objects of traits are encoded as first-class values in Sig.
Considering the similarities between traits and modules, Sig can also be viewed as a languagewith lightweight support of first-class ML modules. Though Sig lacks many features of ML
module systems, such as translucent type members [Leroy 1994; Lillibridge 1997], it still shows
the potential of encoding first-class modules with unified syntax and strong dependent sums.
Moreover, Sig can support signature types that depend on values, e.g., trait { type L : Int; val l :Vec L}. Such type is not supported by 1ML or translucent sums, which depend on System Fω that
do not have full dependent types.

7.3.7

Module Systems for Dependently Typed Calculi

So far we have discussed module systems for core languages which are non-dependent. Several
dependently typed languages, such as Coq [The Coq development team 2016], also employ MLlike module systems. One attempt to formalize such module systems is MC 2 [Courant 2007,
1997] that extends Pure Type Systems with a ML-like module system. The approach of MC 2 ismore traditional. Modules in MC 2 are second-class, which are distinct syntactic levels separated
from core terms of PTS and require duplicated constructs, such as functors and signatures. In
contrast modules/objects in Sig are first-class and unified with core terms. Modules/objects are
encoded by strong sums but not treated as built-in primitives in λIΣ . Moreover, MC 2 aims at
modularizing proofs for proof assistants, while λIΣ and Sig focus on modeling modular constructs
for traditional programming.

129

CHAPTER

8

Conclusion and Future Work

8.1

Conclusion

In this thesis, we explored the design space of dependently typed languages for general-purpose
programming that stand in-between traditional languages and full-spectrum dependently typed
languages. We showed how the advantages of dependent types, especially the economy ofconcepts and added expressiveness, can benefit the designs of traditional languages. In particular,
we developed three dependently typed calculi that combine features for traditional programming:• We developed Pure Iso-Type Systems (PITS), a family of dependently typed calculi withgeneral recursion. PITS employs unified syntax and has comparable simplicity to Pure
Type Systems (PTS). To retain decidable type checking in the presence of general recursion,
we proposed iso-types. Iso-types make every type-level computation steps explicit bycast operators and decouple properties such as decidability of type checking from strong
normalization. We studied three variants of PITS that differ on reduction strategies of casts
and have trade-offs in terms of expressiveness and simplicity of metatheory. We proved
type-safety and decidability of type checking for all variants.
• We developed the λI6 calculus, a dependently typed calculus with subtyping. λI6 is avariant of PITS with extra features for object-oriented programming, including higherorder subtyping, bounded quantification and top types. To address the issues arisingfrom combining dependent types and subtyping, we proposed unified subtyping. Unified
subtyping combines typing and subtyping into a single relation and eliminates the circularityof typing and subtyping. We developed the metatheory of λI6 and proved transitivity of
subtyping and type-safety. We also showed that λI6 can fully subsume System F6 .
• We developed the λIΣ calculus, a dependently typed calculus with subtyping and strong
dependent sums. λIΣ employs the approach of unified subtyping and is a variant of λI6 .
λIΣ also features iso-strong sums whose destructors are typed as intermediate type-levelapplications instead of direct substitutions. Call-by-value casts are capable of performing
necessary type-level computation without the need of full casts. We proved transitivity
and type-safety for λIΣ in the presence of impredicativity. We also showed an applicationof strong sums for encoding Scala-like traits by elaborating surface constructs of Sig into
λIΣ terms.

Chapter 8. Conclusion and Future Work

130

8.2

Future WorkIn this section, we discuss several interesting avenues for future work.
Modeling Functional Languages with PITS. We believe that PITS is suitable to serve as acore language for functional languages with expressiveness in-between traditional languages
and full-spectrum dependently typed languages. For future work, we would like to employ PITS
for modeling traditional functional languages like (older versions of) Haskell and ML with someextra features that come “for free” from the use of dependent types and unified syntax. We
have already shown such possibility in Section 3.2 that PITS can model many type-level features
which are language extensions to classic Haskell or ML. However, writing a new compiler for full
Haskell or ML requires a lot of engineering efforts, even if only considering the classic Haskell
98. We would like to take a more pragmatic approach by modifying existing compilers andreplacing the core language with PITS. For example, JHC [Meacham 2006] is a Haskell compiler
that implements Haskell 98 and has a much smaller code base than the de facto standard Haskell
compiler GHC [The GHC Team 2018]. JHC uses the PTS-style core language Henk [Peyton Jonesand Meijer 1997] for implementing type classes. Based on the work of JHC, we hope to replace
Henk with PITS and implement more language extensions from modern Haskell such as datatype
promotion [Yorgey et al. 2012].
Relax the Value Restriction for Call-by-value PITS. We employ a value restriction in callby-value PITS to retain subject reduction with a simple proof. As discussed in Section 4.2.1, we
will consider an alternative approach by adding cast operators during dynamic semantics for
future work. The proposal is to add two special constructs. The syntax of expressions and values
is extended as follows:e, A ::= · · · | (e1 ; e2 ) | cast↑ [e3 ] (e1 ; e2 )v::= · · · | (v1 ; v2 ) | cast↑ [e3 ] (e1 ; e2 )We use the syntax (e1 ; e2 ) to denote dependent function applications whose arguments are notvalues. A special cast-up operator denoted by cast↑ [e3 ] (e1 ; e2 ) is used to expand types of suchapplications. The typing rules of new constructs are as follows:Γ ` e1 : Πx : A. B

Γ ` e2 : A

x ∈ FV(B )Γ ` (e1 ; e2 ) : (λx : A. B ) e2
Γ ` e1 : Πx : A. B

Γ ` e2 : AΓ ` e3 : A

e3 ,→ e2x ∈ FV(B )Γ ` cast↑ [e3 ] (e1 ; e2 ) : (λx : A. B ) e3
We use the same approach as iso-strong sums (see Section 6.1.2) for the typing of dependent
applications. The typing result is a type-level application that carries the argument e2 . The type
annotation of the special cast-up operator saves an argument e3 which is a beta-expansion of theoriginal argument e2 . The special cast-up operator makes it possible to track the types through8.2. Future Work131

reductions. We have the following new reduction rules:
e1 ,→ e10

e ,→ e 0(e1 ; e2 ) ,→ (e10 ; e2 )(v ; e) ,→ cast↑ [e] (v ; e 0 )cast↓ (cast↑ [e3 ] (e1 ; e2 )) ,→ (e1 ; e2 )cast↓ (v1 ; v2 ) ,→ v1 v2

When trying to reduce (v ; e), we will add a cast-up operator to save the original argument andretain the type for the reduced term: cast↑ [e] (v ; e 0 ). We can use cast↓ operators to eliminate thecast-up operators and the special form of dependent applications. Our preliminary experimentshows that with this approach we can prove type-safety, namely subject reduction and progress
lemmas. Although the typing and reduction rules become complex, we hope that this approach
will help recover some missing expressiveness due to the value restriction.
Push Rules for Full PITS. In Section 4.3.2, we discuss an alternative design of full PITS that
we can use “push rules” as in System FC [Sulzmann et al. 2007] instead of erasing all casts like
Zombie [Sjöberg and Weirich 2015] or Guru [Stump et al. 2008]. For example, we can define apush rule for the case when the function is wrapped by a cast⇑ operator:(cast⇓ [A0 → B 0 ] (λx : A. y)) e ,→ cast⇓ [B 0 ] ((λx : A. y) (cast⇑ [A] e))
The example from Section 4.3.2 can be reduced as follows:(cast⇓ [Int → Int] (λx : Id Int. x )) 3,→ cast⇓ [Int] ((λx : Id Int. x ) (cast⇑ [Id Int] 3)),→ cast⇓ [Int] (cast⇑ [Id Int] 3),→ 3
where Id = λy : ?. y. However, this rule is still limited since it only works when the function is
non-dependent, i.e., with an arrow type and needs to be exactly a lambda term. For future work,
we hope to work out more push rules that can cover all possible cases, so that we can directly
prove type-safety with such rules. We also believe that a direct operational semantics of full PITS
will be helpful to simplify the metatheory and enable the combination of other techniques, suchas unified subtyping.
Consistent Full Reduction for Casts. Full PITS employs two different reduction strategies:
a parallel reduction for casts and a call-by-name reduction for term evaluation (see Section 4.3.1).
This causes some inconsistency in the calculus, e.g. λx : Int. 1 + 1 is a value but reducible byfull casts, and complicates the design. For future work, we would like to explore a consistent full
reduction for both type casts and term evaluation. One possible approach is to use the one-stepfull beta reduction rules (as in Figure 4.9) with a particular order. We have already proved that thecurrent parallel reduction used by full casts has the same expressive power as full beta reduction(see Lemma 4.3.3). This alternative design will not reduce the expressiveness of the calculus.

132

Chapter 8. Conclusion and Future Work

Surface Mechanisms for Iso-Types. We would like to explore mechanisms in surface languages that make iso-types more convenient to use. One possible direction is the lightweight
inference of casts. The end users will be not aware of casts at the surface level and the underlying
compiler will help generating necessary casts for keeping type-safety. Note that we do not expect
a general full inference of casts, which is difficult or even impossible. A more realistic approach is
to infer casts for specific constructs. For example, we have shown how to automatically generate
casts in the target language by an elaboration of surface constructs, such as algebraic datatypes
using Scott encodings (Section 3.2.1) and Scala-like traits using strong sums (Section 6.4.3).
Algorithmic Unified Subtyping. The current algorithmic version of λI6 has a notable difference from the declarative system: the typing and subtyping relations are defined separately(see Section 5.4). This causes complexity in developing metatheory for the algorithmic system.
For example, if we want to prove the decidability, we need cover both subtyping and typing
judgments. The algorithmic system also heavily relies on the erasure of annotations, making it
difficult to prove inversion lemmas. For future work, we hope to develop new algorithmic unified
subtyping judgments for both λI6 and λIΣ calculi. Instead of separated typing and subtyping
judgments, there will be only unified subtyping judgments with two directions: the checking
judgment Γ ` e1 6 e2 ⇐ A and the synthesis judgment Γ ` e1 6 e2 ⇒ A. We would like toprove the soundness and completeness of the new judgments to the original declarative unified
subtyping judgment.
Decidability of Unified Subtyping. We discussed the impact of using the Pi-type rule with fullcontravariance in λI6 , which makes the unified subtyping relation undecidable (see Section 5.6).
However, we did not answer whether the calculus is decidable with the Kernel Fun rule. Like
System F6 , we need to first create an algorithmic presentation of the calculus. In Section 5.4, we
presented a sound and complete algorithmic version of λI6 but did not prove its decidability due
to the complexity of its judgments. For future work, we would like to develop sound and complete
algorithmic versions of λI6 and λIΣ based on the algorithmic unified subtyping judgments andprove their decidability.
More Features for Unified Subtyping. We would like to explore more features for the unified
subtyping relation. For example, as discussed in Section 5.6, the full subtyping of recursion is not
yet supported with unified subtyping due to the pointwise subtyping rules. Similarly, subtyping
applications is not complete, e.g., in rules S-App and SP-App, since the arguments are required
to be fixed. We hope to remove such restrictions by the polarized subtyping approach [Steffen
1998], which provides a mechanism called polarities for a finer-grained control of covariance andcontravariance.
Another example is to extend the bounded quantification with both lower and upper bounds
as in DOT [Amin et al. 2012a]. Currently, only upper bound is supported in λI6 , which follows
the treatment of System F6 . However, the metatheory of DOT is significantly more complex thanλI6 . If only considering to add bounds, we could adopt the method by Stucki [2017] that extendsFω with type intervals (i.e. both upper and lower bounds), which hopefully will not complicate
the metatheory too much. We would also like to take the same approach to add bounds for λIΣ
that currently drops bound quantification for simplicity reasons. One long-term goal is to add

8.2. Future Work133

more features in λIΣ , making it be able to subsume DOT [Amin et al. 2012a] and model more
Scala-like programming idioms.
Relax the Value Restriction in λIΣ . Similarly to call-by-value PITS, λIΣ uses call-by-value
casts and imposes value restrictions. For future work, we would like to relax value restrictions of
λIΣ and introduce a special cast↑ operator, similarly to the previously mentioned proposal forcall-by-value PITS:Γ ` e : Σx : A. B

Γ ` e : Σx : A. B

Γ ` e.2 : (λx : A. B ) (e.1)Γ ` e 0 : Σx : A. B

e ,→ e 0Γ ` cast↑ [e] (e 0 .2) : (λx : A. B ) (e.1)

Cast-up operators will be automatically inserted in the reduction rule of the second projections
and can also be canceled by cast↓ operators:
e ,→ e 0
e.2 ,→ cast↑ [e] (e 0 .2)

cast↓ (cast↑ [e] (e 0 .2)) ,→ e 0 .2

To allow nested second projections, we can use a full cast⇓ operator to eliminate the intermediate
type-level application:e: Σx : A. B
e.2
: (λx : A. B ) (e.1)
cast⇓ (e.2) : B [x 7→ e.1]
Then we can further perform another second projection such as (cast⇓ (e.2)).2 if B is also a
Sigma-type.
Extensions to Sig. The Sig language presented in Section 6.4 is a very simple language built
directly based on λIΣ . It has several language restrictions to keep the design simple and focus onpresenting the application of iso-strong sums. For future work, we would like to support more
surface-level features in Sig. One important missing feature in Sig is subtyping. Since the corelanguage λIΣ already supports (unified) subtyping, we can develop the surface subtyping rules
based subtyping rules in λIΣ . For example, the subtyping rule for traits can be defined as follows:∆ ` Tj 6 Ti0∀i ∈ 1..n, ∃j ∈ 1..m, lj = li0∆ ` trait { type L : T ; val l1 : T1 ; .. ; val lm : Tm } 6
trait { type L : T ; val l10 : T10 ; .. ; val ln0 : Tn0 }This rule follows record subtyping (see Section 2.4.1). Thus, the subtyping relation of traits stillholds for the translated terms in the core since traits are translated to Sigma-types with record
types.
Another example is to support transparent types, which are useful constructs in the ML
module systems. We would like to follow the approach proposed by Leroy [1994] and Lillibridge[1997] to support translucent sum types, i.e., dependent sum types containing equality quantifiers,
denoted by Σx = e : A. B. Transparent type definitions in Sig can be encoded as follows:
trait { type L : T = E ; · · · }ΣL = e : A. · · ·134Chapter 8. Conclusion and Future Work

Translucent sums can be modeled as weak sums using weak opening operations [Lillibridge 1997],
which will (hopefully) have a relatively simple metatheory.

135

APPENDIX

Manual Proofs

A.1

Encoding Weak Sums in λI6

We show the subtyping and typing rules of weak dependent sums are admissible in λI6 .
Lemma A.1.1. The following unified subtyping rule is admissible:Γ ` A1 6 A2 : ?

Γ, x : A1 ` B1 6 B2 : ?

Γ ` (Σx : A1 . B1 ) 6 (Σx : A2 . B2 ) : ?
Proof. By encoding in Section 2.2.1, the conclusion is equivalent toΓ ` (Πz : ?. (Πx : A1 . B1 → z ) → z ) 6 (Πz : ?. (Πx : A2 . B2 → z ) → z ) : ?
We show this relation holds:
Γ, z : ? ` A1 6 A2 : ?
Γ, z : ?, x : A1 ` B1 6 B2 : ?
Γ, z : ?, x : A1 ` (B2 → z ) 6 (B1 → z ) : ?
Γ, z : ? ` (Πx : A2 . B2 → z ) 6 (Πx : A1 . B1 → z ) : ?
Γ, z : ? ` ((Πx : A1 . B1 → z ) → z ) 6 ((Πx : A2 . B2 → z ) → z ) : ?
Γ ` (Πz : ?. (Πx : A1 . B1 → z ) → z ) 6 (Πz : ?. (Πx : A2 . B2 → z ) → z ) : ?

by Lemma 5.3.4
by Lemma 5.3.4
by rule S-Prodby rule S-Prodby rule S-Prodby rule S-Prod

Note that Γ, x : A is syntactic sugar of Γ, x 6 > : A.
Lemma A.1.2. The typing rules for pack and unpack [Schmidt 1994] are admissible.
Proof. The typing rule for pack isΓ ` e1 : AΓ ` e2 : B [x 7→ e1 ]Γ ` pack [e1 , e2 ] as (Σx : A. B ) : (Σx : A. B )By encoding in Section 2.2.1, the conclusion is equivalent toΓ ` (λz : ?. λf : (Πx : A. B → z ). f e1 e2 ) : (Πz : ?. (Πx : A. B → z ) → z )We show this relation holds:

AAppendix A. Manual Proofs

136Γ, z : ?, f : Πx : A. B → z ` e1 : A
Γ, z : ?, f : Πx : A. B → z ` e2 : B [x 7→ e1 ]Γ, z : ?, f : Πx : A. B → z ` f e1 : B [x 7→ e1 ] → z
Γ, z : ?, f : Πx : A. B → z ` f e1 e2 : zΓ ` (λz : ?. λf : (Πx : A. B → z ). f e1 e2 ) : (Πz : ?. (Πx : A. B → z ) → z )by Lemma 5.3.4
by Lemma 5.3.4
by rule S-App
by rule S-App
by rule S-Abs

The typing rule for unpack isΓ ` e1 : (Σx : A. B )Γ, x : A, y : B ` e2 : C

Γ`C :?

Γ ` unpack e1 as [x , y] in e2 : C
By encoding in Section 2.2.1, the typing of e1 and the conclusion are equivalent toΓ ` e1 : (Πz : ?. (Πx : A. B → z ) → z )Γ ` e1 C (λx : A. λy : B . e2 ) : C
where z ∈/ FV(Πx : A. B ) and x, y ∈/ FV(C). We show the conclusion holds:Γ ` e1 C : (Πx : A. B → C ) → CΓ ` (λx : A. λy : B . e2 ) : (Πx : A. B → C )Γ ` e1 C (λx : A. λy : B . e2 ) : C

A.2

by rule S-App and z freshby rule S-Abs and y ∈/ FV(C)by rule S-App

Subsumption of System F6 in λI6

Lemma A.2.1 (Commutativity of Type Substitution). (T1 [X 7→ T2 ])∗ = T1 ∗ [X 7→ T2 ∗ ] holds.
Proof. By induction on the structure of T1 :• Case T1 = >:(>[X 7→ T2 ])∗ = >∗ = >>∗ [X 7→ T2 ∗ ] = >[X 7→ T2 ∗ ] = >• Case T1 = Y :– Case X = Y :(X [X 7→ T2 ])∗ = T2 ∗X ∗ [X 7→ T2 ∗ ] = X [X 7→ T2 ∗ ] = T2 ∗– Case X 6= Y :(Y [X 7→ T2 ])∗ = Y
Y ∗ [X 7→ T2 ∗ ] = Y [X 7→ T2 ∗ ] = Y• Case T1 = U1 → U2 :IH:

(U1 [X 7→ T2 ])∗ = U1 ∗ [X 7→ T2 ∗ ](U2 [X 7→ T2 ])∗ = U2 ∗ [X 7→ T2 ∗ ]((U1 → U2 )[X 7→ T2 ])∗= (U1 [X 7→ T2 ] → U2 [X 7→ T2 ])∗= Πx 6 > : (U1 [X 7→ T2 ])∗ . (U2 [X 7→ T2 ])∗ (x Fresh)= Πx 6 > : (U1 ∗ [X 7→ T2 ∗ ]). (U2 ∗ [X 7→ T2 ∗ ])(U1 → U2 )∗ [X 7→ T2 ∗ ]= (Πx 6 > : U1 ∗ . U2 ∗ )[X 7→ T2 ∗ ] (x Fresh)= Πx 6 >[X 7→ T2 ∗ ] : (U1 ∗ [X 7→ T2 ∗ ]). (U2 ∗ [X 7→ T2 ∗ ])= Πx 6 > : (U1 ∗ [X 7→ T2 ∗ ]). (U2 ∗ [X 7→ T2 ∗ ])• Case T1 = ∀Y 6 U1 . U2 and X 6= Y :A.2. Subsumption of System F6 in λI6
IH:(U1 [X 7→ T2 ])∗ = U1 ∗ [X 7→ T2 ∗ ](U2 [X 7→ T2 ])∗ = U2 ∗ [X 7→ T2 ∗ ]((∀Y 6 U1 . U2 )[X 7→ T2 ])∗= (∀Y 6 U1 [X 7→ T2 ]. U2 [X 7→ T2 ])∗= ΠY 6 (U1 [X 7→ T2 ])∗ : ?. (U2 [X 7→ T2 ])∗= ΠY 6 (U1 ∗ [X 7→ T2 ∗ ]) : ?. (U2 ∗ [X 7→ T2 ∗ ])(∀Y 6 U1 . U2 )∗ [X 7→ T2 ∗ ]= (ΠY 6 U1 ∗ : ?. U2 ∗ )[X 7→ T2 ∗ ]= ΠY 6 (U1 ∗ [X 7→ T2 ∗ ]) : ?[X 7→ T2 ∗ ]. (U2 ∗ [X 7→ T2 ∗ ])= ΠY 6 (U1 ∗ [X 7→ T2 ∗ ]) : ?. (U2 ∗ [X 7→ T2 ∗ ])Lemma A.2.2 (Well-formedness).
1. If ∆ ` T , then ∆∗ ` T ∗ : ?.
2. If ` ∆, then ` ∆∗ .
Proof. By mutual induction on the derivation of ∆ ` T and ` ∆:`∆• Case:∆`>` ∆∗∆∗ ` ? : ?
∆∗ ` > : ?
∆∗ ` >∗ : ?
`∆

by IH
by rule S-Ax
by rule S-TopRefl
by definition of T ∗X 6U ∈ ∆• Case:∆`X` ∆∗X 6 U ∗ : ? ∈ ∆∗∆∗ ` X : ?
∆∗ ` X ∗ : ?
∆ ` U1by IH
by definition of ∆∗by rule S-VarRefl
by definition of T ∗∆ ` U2• Case:∆ ` U1 → U2∆∗ ` U1 ∗ : ?
∆∗ ` U2 ∗ : ?
∆∗ ` > : U1 ∗∆∗ , x 6 > : U1 ∗ ` U2 ∗ : ?
∆∗ ` Πx 6 > : U1 ∗ . U2 ∗ : ?
∆∗ ` (U1 → U2 )∗ : ?
∆ ` U1• Case

by IH
by IH
by rule S-TopRefl
by Lemma 5.3.4 (x Fresh)by rule S-Prodby definition of T ∗∆, X 6 U1 ` U2:

∆ ` ∀X 6 U1 . U2∆∗ ` U1 ∗ : ?
(∆, X 6 U1 )∗ ` U2 ∗ : ?
∆∗ , X 6 U1 ∗ : ? ` U2 ∗ : ?
∆∗ ` ΠX 6 U1 ∗ : ?. U2 ∗ : ?
∆∗ ` (∀X 6 U1 . U2 )∗ : ?
:• Case`∅Trivial.

by IH
by IH
by definition of ∆∗by rule S-Prodby definition of T ∗137

Appendix A. Manual Proofs

138
`∆

∆`U

• Case:` ∆, X 6 U` ∆∗∆∗ ` U ∗ : ?
∆∗ ` ? : ?
` ∆∗ , X 6 U ∗ : ?
` (∆, X 6 U )∗
`∆

by IH
by IH
by rule S-Ax
by rule W-Consby definition of ∆∗∆`U• Case:` ∆, x : U` ∆∗∆∗ ` U ∗ : ?
∆∗ ` > : U ∗` ∆∗ , x 6 > : U ∗` (∆, x : U )∗

by IH
by IH
by rule S-TopRefl
by rule W-Consby definition of ∆∗Lemma A.2.3 (Subtyping). If ∆ ` T1 6 T2 , then ∆∗ ` T1 ∗ 6 T2 ∗ : ?.
Proof. By induction on the derivation of ∆ ` T1 6 T2 :∆`U
• Case:∆`U 6>∆∗ ` U ∗ : ?
∆∗ ` U ∗ 6 > : ?
∆∗ ` U ∗ 6 >∗ : ?

by Lemma A.2.2
by rule S-Top
by definition of T ∗∆`X• Case:∆`X 6X∆∗ ` X ∗ : ?
∆∗ ` X ∗ 6 X ∗ : ?

by Lemma A.2.2
i.e.

X 6 U1 ∈ ∆∆ ` U1 6 U2

• Case:∆ ` X 6 U2
X 6 U1 ∗ : ? ∈ ∆∗∆∗ ` U1 ∗ 6 U2 ∗ : ?
∆∗ ` X 6 U2 ∗ : ?
∆∗ ` X ∗ 6 U2 ∗ : ?
• Case∆ ` T1 6 U 1

by definition of ∆∗by IH
by rule S-VarTransi.e.
∆ ` U2 6 T2:

∆ ` U1 → U2 6 T1 → T2∆∗ ` T1 ∗ 6 U1 ∗ : ?
∆∗ ` U1 ∗ : ?
∆∗ ` T1 ∗ : ?
∆∗ ` > : T1 ∗∆∗ ` U2 ∗ 6 T2 ∗ : ?
∆∗ , x 6 > : T1 ∗ ` U2 ∗ 6 T2 ∗ : ?
∆∗ ` > : U1 ∗∆∗ ` U2 ∗ : ?
∆∗ , x 6 > : U1 ∗ ` U2 ∗ : ?
∆∗ ` (Πx 6 > : U1 ∗ . U2 ∗ ) 6 (Πx 6 > : T1 ∗ . T2 ∗ ) : ?
∆∗ ` (U1 → U2 )∗ 6 (T1 → T2 )∗ : ?

by IH
by Lemma 5.3.1
by Lemma 5.3.1
by rule S-Top
by IH
by Lemma 5.3.4 (x Fresh)by rule S-Top
by Lemma 5.3.1
by Lemma 5.3.4
by rule S-Prodby definition of T ∗A.2. Subsumption of System F6 in λI6139∆, X 6 U ` T1 6 T2

• Case:∆ ` ∀X 6 U . T1 6 ∀X 6 U . T2(∆, X 6 U )∗ ` T1 ∗ 6 T2 ∗ : ?
∆∗ , X 6 U ∗ : ? ` T1 ∗ 6 T2 ∗ : ?
∆∗ , X 6 U ∗ : ? ` T1 ∗ : ?
` ∆∗ , X 6 U ∗ : ?
∆∗ ` U ∗ : ?
` ∆∗∆∗ ` ? : ?
∆∗ ` (ΠX 6 U ∗ : ?. T1 ∗ ) 6 (ΠX 6 U ∗ : ?. T2 ∗ ) : ?
∆∗ ` (∀X 6 U . T1 )∗ 6 (∀X 6 U . T2 )∗ : ?

by IH
by definition of ∆∗by Lemma 5.3.1
by regularity
by inversion of rule W-Consby regularity
by rule S-Ax
by rule S-Prodby definition of T ∗Lemma A.2.4 (Typing). If ∆ ` t : T , then ∆∗ ` t ∗ : T ∗ .
Proof. By induction on the derivation of ∆ ` t : T :`∆x :U ∈ ∆:• Case∆`x :U` ∆∗x 6 > : U ∗ ∈ ∆∗∆∗ ` x ∗ : U ∗by Lemma A.2.2
by definition of ∆∗by rule S-VarRefl∆, x : T1 ` t : T2
• Case:∆ ` λx : T1 . t : T1 → T2(∆, x : T1 )∗ ` t ∗ : T2 ∗∆∗ , x 6 > : T1 ∗ ` t ∗ : T2 ∗∆∗ , x 6 > : T1 ∗ ` T2 ∗ : ?
` ∆∗ , x 6 > : T1 ∗∆∗ ` > : T1 ∗∆∗ ` T1 ∗ : ?
∆∗ ` (λx 6 > : T1 ∗ . t ∗ ) : Πx 6 > : T1 ∗ . T2 ∗∆∗ ` (λx : T1 . t)∗ : (T1 → T2 )∗∆ ` t1 : U1 → U2

by IH
by definition of ∆∗by Lemma 5.3.11
by regularity
by inversion of rule W-Consby inversion of rule W-Consby rule S-Abs
by definition of T ∗ and t ∗∆ ` t2 : U1

• Case:∆ ` t1 t2 : U2∆∗ ` t1 ∗ : (U1 → U2 )∗∆∗ ` t1 ∗ : Πx 6 > : U1 ∗ . U2 ∗∆∗ ` t2 ∗ : U1 ∗∆∗ ` t2 ∗ 6 > : U1 ∗∆∗ ` t1 ∗ t2 ∗ : U2 ∗ [x 7→ t2 ∗ ]U2 ∗ [x 7→ t2 ∗ ] = U2 ∗∆∗ ` (t1 t2 )∗ : U2 ∗• Caseby IH
by definition of T ∗by IH
by rule S-Top
by rule S-App
x Freshby definition of t ∗∆, X 6 T1 ` t : T2
∆ ` ΛX 6 T1 . t : ∀X 6 T1 . T2:

Appendix A. Manual Proofs

140(∆, X 6 T1 )∗ ` t ∗ : T2 ∗∆∗ , X 6 T1 ∗ : ? ` t ∗ : T2 ∗∆∗ , X 6 T1 ∗ : ? ` T2 ∗ : ?
` ∆∗ , X 6 T1 ∗ : ?
∆∗ ` T1 ∗ : ?
` ∆∗∆∗ ` ? : ?
∆∗ ` (λX 6 T1 ∗ : ?. t ∗ ) : ΠX 6 T1 ∗ : ?. T2 ∗∆∗ ` (ΛX 6 T1 . t)∗ : (∀X 6 T1 . T2 )∗• Case∆ ` t : ∀X 6 U1 . U2

∆ ` T 6 U1

by IH
by definition of ∆∗by Lemma 5.3.11
by regularity
by inversion of rule W-Consby regularity
by rule S-Ax
by rule S-Abs
by definition of T ∗ and t ∗:∆ ` t[T ] : U2 [X 7→ T ]∆∗ ` T ∗ 6 U1 ∗ : ?
∆∗ ` t ∗ : (∀X 6 U1 . U2 )∗∆∗ ` t ∗ : ΠX 6 U1 ∗ : ?. U2 ∗∆∗ ` t ∗ T ∗ : U2 ∗ [X 7→ T ∗ ]U2 ∗ [X 7→ T ∗ ] = (U2 [X 7→ T ])∗∆∗ ` (t[T ])∗ : (U2 [X 7→ T ])∗∆`t :T• Case∆`T 6Uby Lemma A.2.3
by IH
by definition of T ∗by rule S-App
by Lemma A.2.1
by definition of t ∗:∆`t :U∆∗ ` t ∗ : T ∗∆∗ ` T ∗ 6 U ∗ : ?
∆∗ ` t ∗ : U ∗

A.3

by IH
by Lemma A.2.3
by rule S-Sub

Soundness of Translation for Sig

Lemma A.3.1 (Translation of Values). If ∆ ` V : Te, then e is a value.

Proof. Trivial by induction on the derivation of ∆ ` V : T
Lemma A.3.2 (Context Well-formedness). If ∆ ` E : T
Proof. Trivial by induction on the derivation of ∆ ` E : T
Lemma A.3.3 (Weakening). If ∆1 , ∆3 ` E : T
E :T
e.

e.
e, then ` ∆e.

e and ` ∆1 , ∆2 , ∆3

Proof. Trivial by induction on the derivation of ∆1 , ∆3 ` E : T
Lemma A.3.4 (Uniqueness). If ∆ ` E : T1
e1 = e2 .

Γ, then ∆1 , ∆2 , ∆3 `e.

e1 and ∆ ` E : T2

Proof. Trivial by induction on the derivation of ∆ ` E : T1Γ.

e2 , then T1 = T2 ande1 .

Definition A.3.1 (Projection-Only Terms). We call E x.L-only-projection if x and L are freevariables in E and x ∈/ FV(E [x .L 7→ y]) for any fresh variable y 6= x. Similarly, bindings ∆, M
and S are x.L-only-projection if they only contain x.L-only-projection terms.
Lemma A.3.5 (Value Projection Substitution). If V1 is a value and V2 is a value, then V1 [x .L 7→
V2 ] is still a value.

A.3. Soundness of Translation for Sig

141

Proof. Trivial by induction on the form of V1 .
Lemma A.3.6 (Projection Substitution). Assume T 0 = trait { type L1 : T3 ; S1 }.
(1) If ∆1 , z = hz1 , z2 i : T 0 , ∆2 ` E : T
e and ∆1 ` V2 : T3
v , where E and ∆2 are z.L1 only-projection, then ∆1 , ∆2 [z .L1 7→ V2 ] ` E [z .L1 7→ V2 ] : T [z .L1 7→ V2 ]e[z1 7→ v ].
(2) If ` ∆1 , z = hz1 , z2 i : T 0 , ∆2
Γ1 , z1 : A, z2 : B , Γ2 and ∆1 ` V2 : T3
z.L1 -only-projection, then ` ∆1 , ∆2 [z .L1 7→ V2 ]
Γ1 , Γ2 [z1 7→ v ].

v , where ∆2 ise and ∆1 ` V2 : T3
v , where M and ∆2 are z.L1 (3) If ∆1 , z = hz1 , z2 i : T 0 , ∆2 ` M : S
only-projection, then ∆1 , ∆2 [z .L1 7→ V2 ] ` M [z .L1 7→ V2 ] : S [z .L1 7→ V2 ]e[z1 7→ v ].
(4) If ∆1 , z = hz1 , z2 i : T 0 , ∆2 ` Se and ∆1 ` V2 : T1
z.L1 -only-projection, then ∆1 , ∆2 [z .L1 7→ V2 ] ` S [z .L1 7→ V2 ]v , where S and ∆2 aree[z1 7→ v ].

Proof. By mutual induction on the derivation of translation. The cases for (2,3,4) are trivial. We
only show proof cases for (1). For source meta-variables, we use E ∗ to denote E [z .L1 7→ V2 ], ∆∗to denote ∆[z .L1 7→ V2 ], etc. For target meta-variables, we use e ∗ to denote e[z1 7→ v ].
• Case TR-Ax: Noting that Type∗ = Type, trivial by IH.
• Case TR-Var, TR-VarM: If x = z, then x is not z.L1 -only-projection. Thus x ∗ = x , the conclusion is trivial by
IH.
• Case TR-Pi:
T1 ∗ is not a trait
T1 , T2 , (∆2 , x : T2 ) are z.L1 -only-projection∆1 , ∆∗2 ` T1 ∗ : Type
A1 ∗
∗
∗
∗
∆1 , ∆2 , x : T1 ` T2 : Type
A2 ∗
∗
∗
∗
∆1 , ∆2 ` (x : T1 ) → T2 : TypeΠx : A1 ∗ . A2 ∗∗∗∆1 , ∆2 ` ((x : T1 ) → T2 ) : Type(Πx : A1 . A2 )∗by definition since V cannot be a trait(see Figure 6.4, similarly for other cases)
by definition
by IH
by IH
by TR-Piby definition• Case TR-PiM:
T1 ∗ = trait { type L : T ∗ ; S ∗ }T1 , T2 , (∆2 , x = hx1 , x2 i : T1 ) are z.L1 -only-projection∆1 , ∆∗2 ` T1 ∗ : Type(Σx1 : A. B )∗∗∆1 , ∆2 , x = hx1 , x2 i : T1 ∗ ` T2 ∗ : TypeC∗∗∗∗
∆1 , ∆2 ` (x : T1 ) → T2 : TypeΠy : (Σx1 : A. B )∗ . (λx1 : A∗ . C ∗ ) (y.1)∗∗∆1 , ∆2 ` ((x : T1 ) → T2 ) : Type(Πy : (Σx1 : A. B ). (λx1 : A. C ) (y.1))∗• Case TR-App:
T1 ∗ is not a trait
E1 , E2 are z.L1 -only-projection∆1 , ∆∗2 ` E1 ∗ : T1 ∗ → T2 ∗
e1 ∗
∗
∗
∗
∗
∆1 , ∆2 ` E2 : T1
e2
∆1 , ∆∗2 ` E1 ∗ E2 ∗ : T2 ∗e1 ∗ e2 ∗∗∗∗∆1 , ∆2 ` (E1 E2 ) : T2(e1 e2 )∗by definition
by definition
by IH
by IH
by TR-Appby definition• Case TR-AppV:
T1 ∗ is not a trait
E , V are z.L1 -only-projection
V ∗ is a value∆1 , ∆∗2 ` E ∗ : (x : T1 ∗ ) → T2 ∗
e1 ∗
∗
∗
∗
∗
∆1 , ∆2 ` V : T1
e2
∆1 , ∆∗2 ` E ∗ V ∗ : T2 ∗ [x 7→ V ∗ ]e1 ∗ e2 ∗∗∗∗∆1 , ∆2 ` (E V ) : (T2 [x 7→ V ])(e1 e2 )∗by definition
by definitionby value substitution
by IH
by IH
by TR-AppVby definition

by definition
by definition
by IH
by IH
by TR-PiM
by definition

Appendix A. Manual Proofs

142• Case TR-AppX: z = y is impossible similarly to case TR-VarM. When z 6= y, y ∗ = y.
T1 ∗ = trait { type L : T ∗ ; S ∗ }E is z.L1 -only-projection∆1 , ∆∗2 ` E ∗ : (x : T1 ∗ ) → T2 ∗e∗∗∗
∆1 , ∆2 ` y : T1
hy1 , y2 as Σx1 : A. B i∗∗∗∗
∆1 , ∆2 ` E y : T2 [x 7→ y]
cast2↓ (e ∗ hy1 , y2 as Σx1 : A. B i∗ )∗∗∗∆1 , ∆2 ` (E y) : (T2 [x 7→ y])(cast2↓ (e hy1 , y2 as Σx1 : A. B i))∗by definition
by definition
by IH
by IH
by TR-AppX
by definition• Case TR-AppM:
T1 ∗ = trait { type L : T ∗ ; S ∗ }V1 ∗ = obj { type L = V ∗ ; M ∗ } as T1 ∗E , V1 are z.L1 -only-projection
V1 ∗ is a valuee∗∆1 , ∆∗2 ` E ∗ : (x : T1 ∗ ) → T2 ∗∗∗∗∆1 , ∆2 ` V1 : T1
he1 , e2 as Σx1 : A. B i∗∗∗∗∗
∆1 , ∆2 ` E V1 : T2 [x .L 7→ V ∗ ]cast2↓ (e ∗ he1 , e2 as Σx1 : A. B i∗ )∗∗∗∆1 , ∆2 ` (E V1 ) : (T2 [x .L 7→ V ])(cast2↓ (e he1 , e2 as Σx1 : A. B i))∗by definition
by definition
by definitionby value subst.
by IH
by IH
by TR-AppM
by definition• Case TR-Lam:
T1 ∗ is not a trait
T1 , E , (∆2 , x : T1 ) are z.L1 -only-projection∆1 , ∆∗2 ` T1 ∗ : TypeA∗
∆1 , ∆∗2 , x : T1 ∗ ` E ∗ : T2 ∗e∗
∆1 , ∆∗2 ` λ(x : T1 ∗ ) ⇒ E ∗ : (x : T1 ∗ ) → T2 ∗λx : A∗ . e ∗∆1 , ∆∗2 ` (λ(x : T1 ) ⇒ E )∗ : ((x : T1 ) → T2 )∗(λx : A. e)∗

by definition
by definition
by IH
by IH
by TR-Lamby definition• Case TR-LamM:
T1 ∗ = trait { type L : T ∗ ; S ∗ }T1 , E , (∆2 , x : T1 ) are z.L1 -only-projection∆1 , ∆∗2 ` T1 ∗ : Type(Σx1 : A. B )∗∗∆1 , ∆2 , x = hx1 , x2 i : T1 ∗ ` E ∗ : T2 ∗
e∗
∗
∗
∗
∗
∆1 , ∆2 ` λ(x : T1 ) ⇒ E : (x : T1 ) → T2 ∗e1where e1 = λy : (Σx1 : A. B )∗ . open y as hx1 , x2 i in e ∗∆1 , ∆∗2 ` (λ(x : T1 ) ⇒ E )∗ : ((x : T1 ) → T2 )∗e2 ∗where e2 = λy : (Σx1 : A. B ). open y as hx1 , x2 i in e

by definition
by definition
by IH
by IH
by TR-LamM
by definition• Case TR-Mod:T ∗ is not a trait
T1 ∗ = trait { type L : T ∗ ; S ∗ }V , M , T1 are z.L1 -only-projection
M ∗ [L 7→ V ∗ ] is z.L1 -only-projection∆1 , ∆∗2 ` V ∗ : T ∗
e1 ∗
∗
∗
∗
∆1 , ∆2 ` M [L 7→ V ] : S ∗ [L 7→ V ∗ ]
e2 ∗
∗
∗
∗
∗
∆1 , ∆2 ` T1 : TypeΣx1 : A . B∆1 , ∆∗2 ` obj { type L = V ∗ ; M ∗ } as T1 ∗ : T1 ∗
∆1 , ∆∗2 ` (obj { type L = V ; M } as T1 )∗ : T1 ∗he1 ∗ , e2 ∗ as Σx1 : A∗ . B ∗ i
he1 , e2 as Σx1 : A. B i∗

by definition
by definition
by definition
by definition
by IH
by IH
by IH
by TR-Modby definition• Case TR-Sig:
T ∗ is not a trait
T , S , (∆2 , L : T ) are z.L1 -only-projection∆1 , ∆∗2 ` T ∗ : TypeA∗∗∗∗
∆1 , ∆2 , L : T ` S
B∗∗∆1 , ∆2 ` trait { type L : T ∗ ; S ∗ } : Type
∆1 , ∆∗2 ` (trait { type L : T ; S })∗ : Type• Case TR-ProjT:

Σx1 : A∗ . B ∗ [L 7→ x1 ](Σx1 : A. B [L 7→ x1 ])∗by definition
by definition
by IH
by IH
by TR-Sigby definitionA.3. Soundness of Translation for Sig

143– Case x = z : we have L = L1 , otherwise x .L is not z .L1 -only-projection. Thus, x .L = z .L1 and(x .L)∗ = V2 .
∆1 , z = hz1 , z2 i : T 0 , ∆2 ` z .L1 : T3
z1
∆1 , z = hz1 , z2 i : T 0 , ∆2 ` x .L : T
x1
T3 = T , z1 = x1
x1 ∗ = v
T3 = T3 ∗∆1 ` V2 : T3 ∗v
∆1 , ∆∗2 ` V2 : T3 ∗v
∆1 , ∆∗2 ` (x .L)∗ : T ∗x1 ∗by TR-ProjT
by conditionby uniquenessby equality
by z ∈/ FV(T3 )by equality
by weakening
by equality– Case x 6= z : we have (x .L)∗ = x .L.
T1 ∗ = trait { type L : T ∗ ; S ∗ }∆1 , ∆∗2 ` x : T1 ∗hx1 , x2 as Σx1 : A∗ . B ∗ i∗∗∆1 , ∆2 ` x .L : T
x1∆1 , ∆∗2 ` (x .L)∗ : T ∗x1 ∗by definition
by IH
by TR-ProjT
by x ∗ = x• Case TR-Proj: Note that x 6= z otherwise x .l is not z.L1 -only-projection. Thus (x .l )∗ = x .l .
T1 ∗ = trait { type L : T ∗ ; S ∗ }∆1 , ∆∗2 ` x : T1 ∗hx1 , x2 as Σx1 : A∗ . B ∗ i∗∗val l : T2 ∈ S∆1 , ∆∗2 ` x .l : T2 ∗ [L 7→ x .L]
x2 .l∆1 , ∆∗2 ` (x .l )∗ : (T2 [L 7→ x .L])∗(x2 .l )∗by definition
by IH
by definition
by TR-Proj
by x ∗ = x

Definition A.3.2 (Non-projection Terms). We call E x-non-projection if it does not contain any
projection form of x (i.e. x .L or x .l where x occurs free in E ). Similarly, bindings ∆, M and S are
x-non-projection if they only contain x-non-projection terms.
Lemma A.3.7 (Value Substitution). If V1 is a x-non-projection value and V2 is a value, thenV1 [x 7→ V2 ] is still a value.
Proof. Trivial by induction on the form of V1 .
Lemma A.3.8 (Typing Substitution).
(1) If ∆1 , z : T1 , ∆2 ` E : T
e and ∆1 ` V2 : T1
then ∆1 , ∆2 [z 7→ V2 ] ` E [z 7→ V2 ] : T [z 7→ V2 ]v , where E and ∆2 are z-non-projection,e[z 7→ v ].

(2) If ` ∆1 , z : T1 , ∆2
Γ1 , z : A, Γ2 and ∆1 ` V2 : T1
then ` ∆1 , ∆2 [z 7→ V2 ]
Γ1 , Γ2 [z 7→ v ].
(3) If ∆1 , z : T1 , ∆2 ` M : Se and ∆1 ` V2 : T1
then ∆1 , ∆2 [z 7→ V2 ] ` M [z 7→ V2 ] : S [z 7→ V2 ](4) If ∆1 , z : T1 , ∆2 ` Se and ∆1 ` V2 : T1
∆1 , ∆2 [z 7→ V2 ] ` S [z 7→ V2 ]e[z 7→ v ].

v , where ∆2 is z-non-projection,v , where M and ∆2 are z-non-projection,e[z 7→ v ].

v , where S and ∆2 are z-non-projection, then

Proof. By mutual induction on the derivation of translation. The cases for (2,3,4) are trivial. We
only show proof cases for (1). For source meta-variables, we use E ∗ to denote E [z 7→ V2 ], ∆∗ todenote ∆[z 7→ V2 ], etc. For target meta-variables, we use e ∗ to denote e[z 7→ v ].
• Case TR-Ax: Trivial by IH.

Appendix A. Manual Proofs

144• Case TR-Var: Suppose E = x ,– Case z = x : Immediate by x ∈/ FV(T ) and weakening.

– Case z 6= x : We have x ∗ = x and x : T ∈ ∆1 , z : T1 , ∆2 . If x : T ∈ ∆1 , then z ∈/ dom(∆1 ) andz∈/ FV(T ). Thus, T ∗ = T . The conclusion holds immediately by weakening. Otherwise, x : T ∈ ∆2
and x : T ∗ ∈ ∆∗2 . Note that ∆2 is z-non-projection, then ` ∆1 , ∆∗2
Γ. Thus, the conclusion holds
by TR-Var.
• Case TR-VarM: Suppose E = y,
– Case z = x : Impossible. x : T1 ∈ ∆ and x = hx1 , x2 i : T1 ∈ ∆ are mismatched.
– Case z 6= x : We have x ∗ = y and x = hx1 , x2 i : T ∈ ∆1 , z : T1 , ∆2 . If x = hx1 , x2 i : T ∈ ∆1 ,then z ∈/ FV(∆1 ) and z ∈/ FV(T ). Thus, T ∗ = T . The conclusion holds immediately by weakening.
Otherwise, x = hx1 , x2 i : T ∈ ∆2 and x = hx1 , x2 i : T ∗ ∈ ∆∗2 . By IH, we have ` ∆1 , ∆∗2
Γ1 , Γ∗2 .
∗∗∗By inversion of TRW-Mod, we have ∆1 , ∆2 ` T : Type(Σx1 : A. B ) The conclusion holds by
TR-VarM.
• Case TR-Pi:
T1 ∗ is not a trait
T1 , T2 , (∆2 , x : T2 ) are z-non-projection∆1 , ∆∗2 ` T1 ∗ : Type
A1 ∗
∗
∗
∗
∆1 , ∆2 , x : T1 ` T2 : Type
A2 ∗
∗
∗
∗
∆1 , ∆2 ` (x : T1 ) → T2 : TypeΠx : A1 ∗ . A2 ∗∗∗∆1 , ∆2 ` ((x : T1 ) → T2 ) : Type(Πx : A1 . A2 )∗by definition
by definition
by IH
by IH
by TR-Piby definition• Case TR-PiM:
T1 ∗ = trait { type L : T ∗ ; S ∗ }T1 , T2 , (∆2 , x = hx1 , x2 i : T1 ) are z-non-projection∆1 , ∆∗2 ` T1 ∗ : Type(Σx1 : A. B )∗∗∆1 , ∆2 , x = hx1 , x2 i : T1 ∗ ` T2 ∗ : TypeC∗∗∗∗
∆1 , ∆2 ` (x : T1 ) → T2 : TypeΠy : (Σx1 : A. B )∗ . (λx1 : A∗ . C ∗ ) (y.1)∗∗∆1 , ∆2 ` ((x : T1 ) → T2 ) : Type(Πy : (Σx1 : A. B ). (λx1 : A. C ) (y.1))∗

by definition
by definition
by IH
by IH
by TR-PiM
by definition• Case TR-App:
T1 ∗ is not a trait
E1 , E2 are z-non-projection∆1 , ∆∗2 ` E1 ∗ : T1 ∗ → T2 ∗
e1 ∗
∗
∗
∗
∗
∆1 , ∆2 ` E2 : T1
e2
∆1 , ∆∗2 ` E1 ∗ E2 ∗ : T2 ∗e 1 ∗ e2 ∗∗∗∗
∆1 , ∆2 ` (E1 E2 ) : T2(e1 e2 )∗by definition
by definition
by IH
by IH
by TR-Appby definition• Case TR-AppV:
T1 ∗ is not a trait
E , V are z-non-projection
V ∗ is a value∆1 , ∆∗2 ` E ∗ : (x : T1 ∗ ) → T2 ∗
e1 ∗
∗
∗
∗
∗
∆1 , ∆2 ` V : T1
e2
∆1 , ∆∗2 ` E ∗ V ∗ : T2 ∗ [x 7→ V ∗ ]e1 ∗ e2 ∗∗∗∗∆1 , ∆2 ` (E V ) : (T2 [x 7→ V ])(e1 e2 )∗by definition
by definitionby value substitution
by IH
by IH
by TR-AppVby definition• Case TR-AppX: z = y is impossible similarly to case TR-VarM. When z 6= y, y ∗ = y.
T1 ∗ = trait { type L : T ∗ ; S ∗ }E is z-non-projection∆1 , ∆∗2 ` E ∗ : (x : T1 ∗ ) → T2 ∗e∗∗∗
∆1 , ∆2 ` y : T1
hy1 , y2 as Σx1 : A. B i∗∗∗∗
∆1 , ∆2 ` E y : T2 [x 7→ y]
cast2↓ (e ∗ hy1 , y2 as Σx1 : A. B i∗ )∗∗∗∆1 , ∆2 ` (E y) : (T2 [x 7→ y])(cast2↓ (e hy1 , y2 as Σx1 : A. B i))∗by definition
by definition
by IH
by IH
by TR-AppX
by definitionA.3. Soundness of Translation for Sig

145• Case TR-AppM:
T1 ∗ = trait { type L : T ∗ ; S ∗ }V1 ∗ = obj { type L = V ∗ ; M ∗ } as T1 ∗E , V1 are z-non-projection
V1 ∗ is a value∆1 , ∆∗2 ` E ∗ : (x : T1 ∗ ) → T2 ∗e∗∗∗∗
∆1 , ∆2 ` V1 : T1
he1 , e2 as Σx1 : A. B i∗∗∗∗∗
∆1 , ∆2 ` E V1 : T2 [x .L 7→ V ∗ ]cast2↓ (e ∗ he1 , e2 as Σx1 : A. B i∗ )∗∗∗∆1 , ∆2 ` (E V1 ) : (T2 [x .L 7→ V ])(cast2↓ (e he1 , e2 as Σx1 : A. B i))∗by definition
by definition
by definitionby value subst.
by IH
by IH
by TR-AppM
by definition• Case TR-Lam:
T1 ∗ is not a trait
T1 , E , (∆2 , x : T1 ) are z-non-projection
A∗∆1 , ∆∗2 ` T1 ∗ : Type∗∗∗e∗
∆1 , ∆2 , x : T1 ` E : T2 ∗∗∗∗∆1 , ∆2 ` λ(x : T1 ) ⇒ E : (x : T1 ∗ ) → T2 ∗λx : A∗ . e ∗∗∗∗∆1 , ∆2 ` (λ(x : T1 ) ⇒ E ) : ((x : T1 ) → T2 )(λx : A. e)∗

by definition
by definition
by IH
by IH
by TR-Lamby definition• Case TR-LamM:
T1 ∗ = trait { type L : T ∗ ; S ∗ }T1 , E , (∆2 , x : T1 ) are z-non-projection∆1 , ∆∗2 ` T1 ∗ : Type(Σx1 : A. B )∗∗∆1 , ∆2 , x = hx1 , x2 i : T1 ∗ ` E ∗ : T2 ∗
e∗
∗
∗
∗
∗
∆1 , ∆2 ` λ(x : T1 ) ⇒ E : (x : T1 ) → T2 ∗e1where e1 = λy : (Σx1 : A. B )∗ . open y as hx1 , x2 i in e ∗∆1 , ∆∗2 ` (λ(x : T1 ) ⇒ E )∗ : ((x : T1 ) → T2 )∗e2 ∗where e2 = λy : (Σx1 : A. B ). open y as hx1 , x2 i in e

by definition
by definition
by IH
by IH
by TR-LamM
by definition• Case TR-Mod:T ∗ is not a trait
T1 ∗ = trait { type L : T ∗ ; S ∗ }V , M , T1 are z-non-projection
M ∗ [L 7→ V ∗ ] is z-non-projection∆1 , ∆∗2 ` V ∗ : T ∗
e1 ∗
∗
∗
∗
∆1 , ∆2 ` M [L 7→ V ] : S ∗ [L 7→ V ∗ ]e2 ∗∆1 , ∆∗2 ` T1 ∗ : TypeΣx1 : A∗ . B ∗∆1 , ∆∗2 ` obj { type L = V ∗ ; M ∗ } as T1 ∗ : T1 ∗
∆1 , ∆∗2 ` (obj { type L = V ; M } as T1 )∗ : T1 ∗he1 ∗ , e2 ∗ as Σx1 : A∗ . B ∗ i
he1 , e2 as Σx1 : A. B i∗

by definition
by definition
by definition
by definition
by IH
by IH
by IH
by TR-Modby definition• Case TR-Sig:
T ∗ is not a trait
T , S , (∆2 , L : T ) are z-non-projection∆1 , ∆∗2 ` T ∗ : TypeA∗∗∗∗
∆1 , ∆2 , L : T ` S
B∗∗∆1 , ∆2 ` trait { type L : T ∗ ; S ∗ } : Type
∆1 , ∆∗2 ` (trait { type L : T ; S })∗ : TypeΣx1 : A∗ . B ∗ [L 7→ x1 ](Σx1 : A. B [L 7→ x1 ])∗by definition
by definition
by IH
by IH
by TR-Sigby definition• Case TR-ProjT: Note that x 6= z otherwise x .L is not x-non-projection. Thus x ∗ = x .
T1 ∗ = trait { type L : T ∗ ; S ∗ }∆1 , ∆∗2 ` x : T1 ∗hx1 , x2 as Σx1 : A∗ . B ∗ i∗∗∆1 , ∆2 ` x .L : T
x1∆1 , ∆∗2 ` (x .L)∗ : T ∗x1 ∗by definition
by IH
by TR-ProjT
by x ∗ = x• Case TR-Proj: Note that x 6= z otherwise x .l is not x-non-projection. Thus x ∗ = x .

Appendix A. Manual Proofs

146
T1 ∗ = trait { type L : T ∗ ; S ∗ }∆1 , ∆∗2 ` x : T1 ∗hx1 , x2 as Σx1 : A∗ . B ∗ i∗∗val l : T2 ∈ S∆1 , ∆∗2 ` x .l : T2 ∗ [L 7→ x .L]
x2 .l∆1 , ∆∗2 ` (x .l )∗ : (T2 [L 7→ x .L])∗(x2 .l )∗by definition
by IH
by definition
by TR-Proj
by x ∗ = x

Lemma A.3.9 (Correctness of Types). If ∆ ` E : T
TypeA.

e, then exists A such that ∆ ` T :Proof. By induction on the derivation of ∆ ` E : T
e. Most cases are trivial by induction
hypothesis. We only show interesting cases where the conclusion type T involves substitution.
• Case TR-AppV:
T2 is x-non-projection∆, x : T1 ` T2 : TypeA2
∆ ` V : T1e2
e2 is a value∆ ` T2 [x 7→ V ] : TypeA2 [x 7→ e2 ]by T1 is not a trait
by inversion of TR-Pi
by premise
by value translation
by substitution• Case TR-AppX:∆, x = hx1 , x2 i : T1 ` T2 : TypeC
T2 is x.L-only-projection∆ ` y.L : Ty1∆ ` T2 [x .L 7→ y.L] : TypeC [x1 7→ y1 ]∆ ` T2 [x 7→ y] : TypeC [x1 7→ y1 ]by inversion of TR-PiM
by inversion of TR-PiM
by TR-ProjT
by projection substitution• Case TR-AppM:∆, x = hx1 , x2 i : T1 ` T2 : TypeC
T2 is x.L-only-projection∆`V :Te1
e1 is a value∆ ` T2 [x .L 7→ V ] : TypeC [x1 7→ e1 ]by inversion of TR-PiM
by inversion of TR-PiM
by inversion of TR-Mod
by translation of values
by projection substitution• Case TR-Proj:∆ ` T1 : TypeΣx1 : A. B
T is not a trait∆, L : T ` T2 : TypeA2
T2 is L-non-projection∆ ` x .L : T
x1∆ ` T2 [L 7→ x .L] : Type
A2 [L 7→ x1 ]by IH
by inversion of TR-Sig
by inversion of TRS-Sig
by T is not a traitby TR-ProjT
by substitution

Lemma A.3.10 (Soundness of Translation).
(1) If ` ∆Γ, then ` Γ.

(2) If ` ∆Γ and ∆ ` S(3) Given ` ∆A, then Γ ` A : ?.

Γ, if ∆ ` E : T

e and ∆ ` T : TypeA, then Γ ` e : A.

e, ` ∆
Γ andProof. By simultaneous induction on the derivation of ∆ ` E : T∆`M :Se. The cases in (1) and (2) are trivial. We only show the proofs regarding (3).

A.3. Soundness of Translation for Sig

147• Case TR-Ax:
`Γ
Γ`?:?

by IH
by SP-Ax• Case TR-Var:
x :A ∈ Γ∆ ` T : Type`ΓΓ`x :AA

by TRW-Cons
by TRW-Cons
by IH
by SP-Var• Case TR-VarM:
x1 : A, x2 : B ∈ ΓΓ ` x1 : AΓ ` x2 : B
Γ, x1 : A ` B : ?
Γ ` hx1 , x2 as Σx1 : A. B i : Σx1 : A. B

by TRW-Mod
by SP-Varby SP-Varby well-formedness of Σx1 : A. B
by SP-Pair• Case TR-Pi:
Γ ` A1 : ?
Γ, x : A1 ` A2 : ?
Γ ` Πx : A1 . A2 : ?

by IH
by IH and TRW-Cons
by SP-Prod• Case TR-PiM:Γ ` Σx1 : A. B : ?
Γ, x1 : A, x2 : B ` C : ?
x2 ∈/ FV(C)Γ ` λx1 : A. C : A → ?
Γ, y : Σx1 : A. B ` y.1 : A
Γ, y : Σx1 : A. B ` (λx1 : A. C ) (y.1) : AΓ ` Πy : (Σx1 : A. B ). (λx1 : A. C ) (y.1) : ?

by IH
by IH and TRW-Mod
by T2 is x.L-only-projection
by IH and SP-Abs
by SP-Fst
by SP-Appby SP-Prod• Case TR-App:∆ ` T1 → T2 : Type∆ ` T1 : TypeA1
∆ ` T2 : TypeA2Γ ` e1 : A1 → A2
Γ ` e2 : A1
Γ ` e1 e2 : A2

A1 → A2

by correctness of types
by inversion of TR-Pi
by inversion of TR-Pi
by IH
by IH
by SP-App• Case TR-AppV:∆ ` (x : T1 ) → T2 : TypeΠx : A1 . A2
∆ ` T1 : TypeA1∆, x : T1 ` T2 : TypeA2Γ ` e1 : Πx : A1 . A2
Γ ` e2 : A1
e2 is a valueΓ ` e1 e2 : A2 [x 7→ e2 ]• Case TR-AppX:

by correctness of types
by inversion of TR-Pi
by inversion of TR-Pi
by IH
by IH
by translation of values
by SP-AppVAppendix A. Manual Proofs148∆ ` (x : T1 ) → T2 : Type
A1
where A1 = Πy : (Σx1 : A. B ). (λx1 : A. C ) (y.1)∆ ` T1 : TypeΣx1 : A. B
T2 is x.L-only-projection
y = hy1 , y2 i : T1 ∈ ∆y1 : A, y2 : B ∈ Γ∆ ` y.L : T
y1∆, x = hx1 , x2 i : T1 ` T2 : TypeC
∆ ` T2 [x .L 7→ y.L] : TypeC [x1 7→ y1 ]∆ ` T2 [x 7→ y] : TypeC [x1 7→ y1 ]Γ ` e : Πy : (Σx1 : A. B ). (λx1 : A. C ) (y.1)Γ ` hy1 , y2 as Σx1 : A. B i : Σx1 : A. B
Γ ` cast2↓ (e hy1 , y2 as Σx1 : A. B i) : C [x1 7→ y1 ]by correctness of types
by inversion of TR-PiM
by inversion of TR-PiM
by inversion of TR-VarM
by inversion of TRW-Mod
by TR-ProjT
by inversion of TR-PiM
by projection substitution
by IH
by IH
by SP-CastDn and SP-AppV• Case TR-AppM:∆ ` (x : T1 ) → T2 : Type
A1
where A1 = Πy : (Σx1 : A. B ). (λx1 : A. C ) (y.1)∆ ` T1 : TypeΣx1 : A. B∆, x = hx1 , x2 i : T1 ` T2 : TypeC
T2 is x.L-only-projection∆`V :Te1
e1 is a value∆ ` T2 [x .L 7→ V ] : TypeC [x1 7→ e1 ]Γ ` e : Πy : (Σx1 : A. B ). (λx1 : A. C ) (y.1)Γ ` he1 , e2 as Σx1 : A. B i : Σx1 : A. B
Γ ` cast2↓ (e he1 , e2 as Σx1 : A. B i) : C [x1 7→ e1 ]by correctness of types
by inversion of TR-PiM
by inversion of TR-PiM
by inversion of TR-PiM
by inversion of TR-Mod
by translation of values
by projection substitution
by IH
by IH
by SP-CastDn and SP-AppV• Case TR-Lam:∆, x : T1 ` T2 : TypeBΓ`A:?
Γ, x : A ` e : B∆ ` (x : T1 ) → T2 : TypeΓ ` λx : A. e : Πx : A. B

Πx : A. B

by correctness of types
by IH
by IH
by TR-Pi
by SP-Abs• Case TR-LamM:∆, x = hx1 , x2 i : T1 ` T2 : TypeCΓ ` Σx1 : A. B : ?
Γ, x1 : A, x2 : B ` e : C∆ ` (x : T1 ) → T2 : Type
A1
where A1 = Πy : (Σx1 : A. B ). (λx1 : A. C ) (y.1)
x2 ∈/ FV(C)Γ, y : Σx1 : A. B ` open y as hx1 , x2 i in e : (λx1 : A. C ) (y.1)Γ ` λy : (Σx1 : A. B ). open y as hx1 , x2 i in e : A1
• Case TR-Mod:∆ ` T : TypeA∆, L : T ` S
B [x1 7→ L]
S is L-non-projection∆ ` S [L 7→ V ]B [x1 7→ e1 ]Γ ` e1 : AΓ ` e2 : B [x1 7→ e1 ]e1 is a valueΓ ` he1 , e2 as Σx1 : A. B i : Σx1 : A. B
• Case TR-Sig:by inversion of TR-Sig
by inversion of TR-Sig
by T is not a trait
by substitution
by IH
by IH
by translation of values
by SP-Pairby correctness of types
by IH
by IH
by TR-PiM
by T2 is x.L-only-projection
by SP-Open
by SP-Abs

A.3. Soundness of Translation for SigΓ`A:?
Γ, L : A ` B : ?
Γ, x1 : A ` B [L 7→ x1 ] : ?
Γ ` Σx1 : A. B [L 7→ x1 ] : ?

149

by IH
by IH
by substitution
by SP-Sig• Case TR-ProjT:x = hx1 , x2 i : T1 ∈ ∆x1 : A, x2 : B ∈ Γ∆ ` T1 : TypeΣx1 : A. B
∆ ` T : TypeAΓ ` x1 : A

by inversion of TR-VarM
by inversion of TRW-Mod
by inversion of TRW-Mod
by inversion of TR-Sig
by SP-Var• Case TR-Proj:x = hx1 , x2 i : T1 ∈ ∆x1 : A, x2 : B ∈ Γ∆ ` T1 : TypeΣx1 : A. B
∆ ` T : TypeA∆, L : T ` S
B∆, L : T ` T2 : TypeA2
l : A2 ∈ B
Γ, L : A ` x2 .l : A2
T2 is L-non-projection∆ ` x .L : T
x1∆ ` T2 [L 7→ x .L] : Type
A2 [L 7→ x1 ]Γ ` x1 : AΓ ` x2 .l : A2 [L 7→ x1 ]by inversion of TR-VarM
by inversion of TRW-Mod
by inversion of TRW-Mod
by inversion of TR-Sig
by inversion of TR-Sig
by inversion of TS-Sig
by inversion of TS-Sig
by record projection
by T is not a traitby TR-ProjT
by substitution
by SP-Varby substitution

151

References

Andreas Abel and Dulma Rodriguez. 2008. Syntactic metatheory of higher-order subtyping. In International
Workshop on Computer Science Logic (CSL ’08). 446–460.
Beniamino Accattoli and Giulio Guerrieri. 2016. Open Call-by-Value. In Programming Languages andSystems, Atsushi Igarashi (Ed.). Springer International Publishing, Cham, 206–226.
Wilhelm Ackermann. 1928. Zum hilbertschen aufbau der reellen zahlen. Math. Ann. 99, 1 (1928), 118–133.
Robin Adams. 2006. Pure type systems with judgemental equality. Journal of Functional Programming 16,
02 (2006), 219–246.
Robin Adams. 2008. A Survey of Predicativity. (2008). https://www.cs.ru.nl/R.Adams/predicativity3.pdf
Thorsten Altenkirch, Nils Anders Danielsson, Andres Löh, and Nicolas Oury. 2010. ΠΣ: Dependent Types
without the Sugar. In Functional and Logic Programming, Matthias Blume, Naoki Kobayashi, and Germán
Vidal (Eds.). Springer Berlin Heidelberg, Berlin, Heidelberg, 40–55.
Nada Amin, Samuel Grütter, Martin Odersky, Tiark Rompf, and Sandro Stucki. 2016. The essence ofdependent object types. In A List of Successes That Can Change the World. Springer, 249–272.
Nada Amin, Adriaan Moors, and Martin Odersky. 2012a. Dependent object types. In 19th International
Workshop on Foundations of Object-Oriented Languages (FOOL ’12).
Nada Amin, Adriaan Moors, and Martin Odersky. 2012b. Dependent object types. In 19th International
Workshop on Foundations of Object-Oriented Languages (FOOL ’12). ACM.
Nada Amin, Tiark Rompf, and Martin Odersky. 2014. Foundations of path-dependent types. In OOPSLA ’14.
ACM, 233–249.
David Aspinall and Adriana Compagnoni. 1996. Subtyping dependent types. In LICS ’96. 86–97.
Lennart Augustsson. 1998. Cayenne — a Language with Dependent Types. In Proceedings of the Third ACM
SIGPLAN International Conference on Functional Programming (ICFP ’98). ACM, New York, NY, USA,239–250. https://doi.org/10.1145/289423.289451
Henk Barendregt. 1991. Introduction to generalized type systems. Journal of Functional Programming 1, 2
(1991), 125–154.
Henk Barendregt. 1992. Lambda Calculi with Types. In Handbook of Logic in Computer Science, Vol. 2.
117–309.
Yves Bertot and Pierre Castran. 2010. Interactive Theorem Proving and Program Development: Coq’Art The
Calculus of Inductive Constructions (1st ed.). Springer Publishing Company, Incorporated.

152

References

William J. Bowman, Youyou Cong, Nick Rioux, and Amal Ahmed. 2017. Type-preserving CPS Translationof Σ and Π Types is Not Not Possible. Proc. ACM Program. Lang. 2, POPL, Article 22 (Dec. 2017), 33 pages.
https://doi.org/10.1145/3158110
Gilad Bracha, Martin Odersky, David Stoutamire, and Philip Wadler. 1998. Making the Future Safe for the
Past: Adding Genericity to the Java Programming Language. In Proceedings of the 13th ACM SIGPLAN
Conference on Object-oriented Programming, Systems, Languages, and Applications (OOPSLA ’98). ACM,
New York, NY, USA, 183–200. https://doi.org/10.1145/286936.286957
Edwin Brady. 2013. Idris, a general-purpose dependently typed programming language: Design andimplementation. Journal of Functional Programming 23, 05 (2013), 552–593.
Edwin C. Brady. 2011. IDRIS — Systems Programming Meets Full Dependent Types. In Proceedings of the
5th ACM Workshop on Programming Languages Meets Program Verification (PLPV ’11). ACM, New York,NY, USA, 43–54. https://doi.org/10.1145/1929529.1929536
Kim B. Bruce, Luca Cardelli, and Benjamin C. Pierce. 1999. Comparing object encodings. Information andComputation 155, 1-2 (1999), 108–133.
Joana Campos and Vasco T. Vasconcelos. 2015. Imperative objects with dependent types. In Proceedings ofthe 17th Workshop on Formal Techniques for Java-like Programs (FTfJP ’15). ACM, 2:1–2:6.
Joana Campos and Vasco T. Vasconcelos. 2018. Dependent Types for Class-based Mutable Objects. In 32nd
European Conference on Object-Oriented Programming (ECOOP 2018) (Leibniz International Proceedings inInformatics (LIPIcs)), Todd Millstein (Ed.), Vol. 109. Schloss Dagstuhl–Leibniz-Zentrum fuer Informatik,
Dagstuhl, Germany, 13:1–13:28. https://doi.org/10.4230/LIPIcs.ECOOP.2018.13
Luca Cardelli. 1986a. Amber. In Combinators and Functional Programming Languages. Springer Berlin
Heidelberg, 21–47.
Luca Cardelli. 1986b. A Polymorphic lambda-calculus with Type: Type. Digital Systems Research Center.
Luca Cardelli, Simone Martini, John C. Mitchell, and Andre Scedrov. 1994. An extension of system F with
subtyping. Information and Computation 109, 1-2 (1994), 4–56.
Luca Cardelli and Peter Wegner. 1985. On understanding types, data abstraction, and polymorphism. ACM
Computing Surveys (CSUR) 17, 4 (1985), 471–523.
Chris Casinghino. 2014. Combining Proofs and Programs. Ph.D. Dissertation. The University of Pennsylvania.
Chris Casinghino, Vilhelm Sjöberg, and Stephanie Weirich. 2014. Combining Proofs and Programs in a
Dependently Typed Language. In Proceedings of the 41st ACM SIGPLAN-SIGACT Symposium on Principles
of Programming Languages (POPL ’14). ACM, New York, NY, USA, 33–45. https://doi.org/10.1145/2535838.
2535883
Giuseppe Castagna and Gang Chen. 2001. Dependent types with subtyping and late-bound overloading.
Information and Computation 168, 1 (2001), 1–67.
Gang Chen. 1997. Subtyping calculus of construction. Mathematical Foundations of Computer Science 1997
(1997), 189–198.
Gang Chen. 1998. Dependent type system with subtyping (I) type level transitivity elimination. Journal ofComputer Science and Technology 13, 6 (1998), 564–578.
Gang Chen. 2003. Coercive Subtyping for the Calculus of Constructions. In Proceedings of the 30th ACM
SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL ’03). ACM, 150–159.

References

153

James Cheney and Ralf Hinze. 2003. First-Class Phantom Types. Technical Report CUCIS TR2003-1901.
Adam Chlipala. 2013. Certified Programming with Dependent Types: A Pragmatic Introduction to the Coq
Proof Assistant. The MIT Press.
Adriana Compagnoni and Healfdene Goguen. 2003. Typed operational semantics for higher-order subtyping.
Information and Computation 184, 2 (2003), 242–297.
Adriana Beatriz Compagnoni. 1995. Higher-order subtyping with intersection types. Ph.D. Dissertation.
University of Nijmegen.
Thierry Coquand. 1986. An analysis of Girard’s paradox. Ph.D. Dissertation. INRIA.
Thierry Coquand and Gérard Huet. 1988. The Calculus of Constructions. Information and Computation 76(1988), 95–120.
Judicaël Courant. 1997. A module calculus for pure type systems. In Typed Lambda Calculi and Applications,
Philippe de Groote and J. Roger Hindley (Eds.). Springer Berlin Heidelberg, Berlin, Heidelberg, 112–128.
Judicaël Courant. 2007. A module calculus for Pure Type Systems. Journal of Functional Programming 17, 3(2007), 287–352.
Karl Crary, Robert Harper, and Sidd Puri. 1999. What is a Recursive Module?. In Proceedings of the ACM
SIGPLAN 1999 Conference on Programming Language Design and Implementation (PLDI ’99). ACM, New
York, NY, USA, 50–63. https://doi.org/10.1145/301618.301641
Pierre-Louis Curien and Giorgio Ghelli. 1992. Coherence of subsumption, minimum typing and typechecking in F6. Mathematical structures in computer science 2, 01 (1992), 55–91.
Derek Dreyer. 2005. Understanding and Evolving the ML Module System. Ph.D. Dissertation. Carnegie
Mellon University.
Richard A. Eisenberg. 2016. Dependent types in haskell: Theory and practice. Ph.D. Dissertation. Universityof Pennsylvania.
Richard A. Eisenberg, Dimitrios Vytiniotis, Simon Peyton Jones, and Stephanie Weirich. 2014. Closed Type
Families with Overlapping Equations. In Proceedings of the 41st ACM SIGPLAN-SIGACT Symposium on
Principles of Programming Languages (POPL ’14). ACM, New York, NY, USA, 671–683. https://doi.org/10.
1145/2535838.2535856
Leonidas Fegaras and Tim Sheard. 1996. Revisiting Catamorphisms over Datatypes with Embedded
Functions (or, Programs from Outer Space). In Proceedings of the 23rd ACM SIGPLAN-SIGACT Symposiumon Principles of Programming Languages (POPL ’96). ACM, New York, NY, USA, 284–294. https://doi.org/
10.1145/237721.237792
Herman Geuvers. 1995. A short and flexible proof of strong normalization for the calculus of constructions.
In Types for Proofs and Programs, Peter Dybjer, Bengt Nordström, and Jan Smith (Eds.). Springer Berlin
Heidelberg, Berlin, Heidelberg, 14–38.
Jean-Yves Girard. 1972. Interprétation fonctionelle et élimination des coupures de l’arithmétique d’ordre
supérieur. Ph.D. Dissertation. Université Paris VII.
Brian Goetz. 2016. JEP 286: Local-Variable Type Inference. http://openjdk.java.net/jeps/286
James Gosling, Bill Joy, and Guy L. Steele. 1996. The Java Language Specification (1st ed.). Addison-WesleyLongman Publishing Co., Inc., Boston, MA, USA.

154

References

Adam Michael Gundry. 2013. Type Inference, Haskell and Dependent Types. Ph.D. Dissertation. Universityof Strathclyde.
Cordelia Hall, Kevin Hammond, Simon Peyton Jones, and Philip Wadler. 1994. Type classes in Haskell. In
Programming Languages and Systems — ESOP ’94, Donald Sannella (Ed.). Springer Berlin Heidelberg,
Berlin, Heidelberg, 241–256.
Robert Harper. 2013. Practical foundations for programming languages (1st ed.). Cambridge University
Press.
Robert Harper and Mark Lillibridge. 1994. A Type-theoretic Approach to Higher-order Modules with
Sharing. In Proceedings of the 21st ACM SIGPLAN-SIGACT Symposium on Principles of Programming
Languages (POPL ’94). ACM, New York, NY, USA, 123–137. https://doi.org/10.1145/174675.176927
Robert Harper and John C. Mitchell. 1993. On the Type Structure of Standard ML. ACM Trans. Program.
Lang. Syst. 15, 2 (April 1993), 211–252. https://doi.org/10.1145/169701.169696
James G. Hook and Douglas J. Howe. 1986. Impredicative Strong Existential Equivalent to Type:Type.
Technical Report. Ithaca, NY, USA.
William A. Howard. 1980. The formulae-as-types notion of construction. To HB Curry: essays on combinatory
logic, lambda calculus and formalism 44 (1980), 479–490.
DeLesley S. Hutchins. 2010. Pure Subtype Systems. In Proceedings of the 37th Annual ACM SIGPLAN-SIGACT
Symposium on Principles of Programming Languages (POPL ’10). ACM, 287–298.
Atshushi Igarashi, Benjamin Pierce, and Philip Wadler. 1999. Featherweight Java: A Minimal Core Calculus
for Java and GJ. In Proceedings of the 14th ACM SIGPLAN Conference on Object-oriented Programming,
Systems, Languages, and Applications (OOPSLA ’99). ACM, New York, NY, USA, 132–146. https://doi.org/
10.1145/320384.320395
Mark P. Jones. 1993. A System of Constructor Classes: Overloading and Implicit Higher-order Polymorphism.
In Proceedings of the Conference on Functional Programming Languages and Computer Architecture (FPCA’93). ACM, New York, NY, USA, 52–61. https://doi.org/10.1145/165180.165190
Mark P. Jones. 2000. Type Classes with Functional Dependencies. In Programming Languages and Systems,
Gert Smolka (Ed.). Springer Berlin Heidelberg, Berlin, Heidelberg, 230–244.
Jonas Kaiser, Tobias Tebbi, and Gert Smolka. 2017. Equivalence of System F and λ2 in Coq Based on Context
Morphism Lemmas. In Proceedings of the 6th ACM SIGPLAN Conference on Certified Programs and Proofs(CPP ’17). ACM, 222–234.
Garrin Kimmell, Aaron Stump, Harley D. Eades, III, Peng Fu, Tim Sheard, Stephanie Weirich, Chris
Casinghino, Vilhelm Sjöberg, Nathan Collins, and Ki Yung Ahn. 2012. Equational Reasoning About
Programs with General Recursion and Call-by-value Semantics. In Proceedings of the Sixth Workshop
on Programming Languages Meets Program Verification (PLPV ’12). ACM, New York, NY, USA, 15–26.
https://doi.org/10.1145/2103776.2103780
Xavier Leroy. 1990. The ZINC Experiment: An Economical Implementation of the ML Language. Technical
Report 117. INRIA. http://pauillac.inria.fr/~xleroy/bibrefs/Leroy-ZINC.html
Xavier Leroy. 1994. Manifest Types, Modules, and Separate Compilation. In Proceedings of the 21st ACM
SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL ’94). ACM, New York, NY,
USA, 109–122. https://doi.org/10.1145/174675.176926

References

155

Xavier Leroy, Damien Doligez, Alain Frisch, Jacques Garrigue, Didier Rémy, and Jérôme Vouillon. 2018.
The OCaml system release 4.07: Documentation and user’s manual. http://caml.inria.fr/pub/docs/
manual-ocaml/ Release 4.07.
Mark Lillibridge. 1997. Translucent sums: A foundation for higher-order module systems. Ph.D. Dissertation.
Carnegie Mellon University.
Yong Luo and Zhaohui Luo. 2004. Combining Incoherent Coercions for Σ -Types. In Types for Proofs andPrograms, Stefano Berardi, Mario Coppo, and Ferruccio Damiani (Eds.). Springer Berlin Heidelberg,
Berlin, Heidelberg, 276–292.
David B. MacQueen. 1986. Using Dependent Types to Express Modular Structure. In Proceedings of the
13th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages (POPL ’86). ACM, New
York, NY, USA, 277–286. https://doi.org/10.1145/512644.512670
Simon Marlow. 2010. Haskell 2010 Language Report. https://www.haskell.org/definition/haskell2010.pdf
2010.
Simon Marlow et al. 2010. Haskell 2010 language report. Available online http://www. haskell. org/(May2011) (2010).
John Meacham. 2006. Jhc User’s Manual. http://repetae.net/computer/jhc/manual.html
Microsoft Corporation. 2016. TypeScript Language Specification. https://github.com/Microsoft/TypeScript/
blob/master/doc/spec.md Version 1.8.
Robin Milner, Mads Tofte, and Robert Harper. 1990. The Definition of Standard ML. MIT Press, Cambridge,
MA, USA.
John C. Mitchell and Gordon D. Plotkin. 1988. Abstract Types Have Existential Type. ACM Trans. Program.
Lang. Syst. 10, 3 (July 1988), 470–502. https://doi.org/10.1145/44501.45065
T. Æ. Mogensen. 1992. Theoretical pearls: Efficient self-interpretation in lambda calculus. Journal of
Functional Programming 2, 3 (1992), 345–364.
Adriaan Moors, Frank Piessens, and Martin Odersky. 2008. Generics of a Higher Kind. In OOPSLA ’08.
ACM, 423–438.
Ulf Norell. 2007a. Towards a practical programming language based on dependent type theory. Ph.D.
Dissertation. Chalmers University of Technology.
Ulf Norell. 2007b. Towards a practical programming language based on dependent type theory. Ph.D.
Dissertation. Chalmers University of Technology.
Martin Odersky, Philippe Altherr, Vincent Cremet, Burak Emir, Sebastian Maneth, Stéphane Micheloud,Nikolay Mihaylov, Michel Schinz, Erik Stenman, and Matthias Zenger. 2004. An Overview of the Scala
Programming Language. Technical Report IC/2004/64. EPFL Lausanne, Switzerland.
Martin Odersky, Vincent Cremet, Christine Röckl, and Matthias Zenger. 2003. A nominal theory of objects
with dependent types. In European Conference on Object-Oriented Programming (ECOOP ’03). Springer,
201–224.
Luca Paolini and Simona Ronchi Della Rocca. 1999. Call-by-value Solvability. RAIRO-Theoretical Informatics
and Applications 33, 6 (1999), 507–534.
Simon Peyton Jones and Erik Meijer. 1997. Henk: a Typed Intermediate Language. In Types in Compilation
Workshop.

156

References

Simon Peyton Jones, Geoffrey Washburn, and Stephanie Weirich. 2004. Wobbly types: type inference forgeneralised algebraic data types. Technical Report MS-CIS-05-26. University of Pennsylvania.
F. Pfenning and C. Elliott. 1988. Higher-order Abstract Syntax. In Proceedings of the ACM SIGPLAN 1988
Conference on Programming Language Design and Implementation (PLDI ’88). ACM, New York, NY, USA,
199–208. https://doi.org/10.1145/53990.54010
Frank Pfenning and Carsten Schürmann. 1999. System Description: Twelf — A Meta-Logical Frameworkfor Deductive Systems. In Proceedings of the International Conference on Automated Deduction. 202–206.
Benjamin C. Pierce. 1992. Bounded quantification is undecidable. In Proceedings of the 19th ACM SIGPLANSIGACT symposium on Principles of programming languages (POPL ’92). ACM, 305–315.
Benjamin C Pierce. 2002. Types and programming languages. MIT press.
Benjamin C. Pierce and Martin Steffen. 1997. Higher-order subtyping. Theoretical computer science 176, 1(1997), 235–282.
Benjamin C. Pierce and David N. Turner. 1994. Simple type-theoretic foundations for object-oriented
programming. Journal of functional programming 4, 02 (1994), 207–247.
Benjamin C. Pierce and David N. Turner. 2000. Local type inference. ACM Transactions on Programming
Languages and Systems (TOPLAS) 22, 1 (2000), 1–44.
Robert Pollack. 2002. Dependently Typed Records in Type Theory. Formal Aspects of Computing 13, 3 (01Jul 2002), 386–402. https://doi.org/10.1007/s001650200018
Marianna Rapoport, Ifaz Kabir, Paul He, and Ondřej Lhoták. 2017. A Simple Soundness Proof for Dependent
Object Types. Proc. ACM Program. Lang. 1, OOPSLA, Article 46 (Oct. 2017), 27 pages. https://doi.org/10.
1145/3133870
John C. Reynolds. 1974. Towards a theory of type structure. In Proceedings of the ‘Colloque sur la Programmation’. Paris, France, 408–425.
Tiark Rompf and Nada Amin. 2016. Type soundness for dependent object types (DOT). In Proceedings ofthe 2016 ACM SIGPLAN International Conference on Object-Oriented Programming, Systems, Languages,
and Applications (OOPSLA ’16). ACM, 624–641.
Andreas Rossberg. 2015. 1ML – Core and Modules United (F-ing First-class Modules). In Proceedings of the20th ACM SIGPLAN International Conference on Functional Programming (ICFP 2015). ACM, New York,NY, USA, 35–47. https://doi.org/10.1145/2784731.2784738
Andreas Rossberg, Claudio V. Russo, and Derek Dreyer. 2010. F-ing Modules. In Proceedings of the 5th ACM
SIGPLAN Workshop on Types in Language Design and Implementation (TLDI ’10). ACM, New York, NY,
USA, 89–102. https://doi.org/10.1145/1708016.1708028
Nathanael Schärli, Stéphane Ducasse, Oscar Nierstrasz, and Andrew P Black. 2003. Traits: Composable
units of behaviour. In European Conference on Object-Oriented Programming. Springer, 248–274.
David A. Schmidt. 1994. The Structure of Typed Programming Languages. MIT Press.
Paula G. Severi and Fer-Jan J. de Vries. 2012. Pure Type Systems with Corecursion on Streams: From Finite toInfinitary Normalisation. In Proceedings of the 17th ACM SIGPLAN International Conference on Functional
Programming (ICFP ’12). ACM, New York, NY, USA, 141–152. https://doi.org/10.1145/2364527.2364550

References

157

Tim Sheard and Simon Peyton Jones. 2002. Template Meta-programming for Haskell. In Proceedings ofthe 2002 ACM SIGPLAN Workshop on Haskell (Haskell ’02). ACM, New York, NY, USA, 1–16. https://doi.org/10.1145/581690.581691
Jeremy G. Siek and Walid Taha. 2006. Gradual typing for functional languages. In Scheme and Functional
Programming. 81–92.
Vincent Siles and Hugo Herbelin. 2012. Pure Type System conversion is always typable. Journal of
Functional Programming 22, 2 (2012), 153–180.
Vilhelm Sjöberg. 2015. A Dependently Typed Language with Nontermination. Ph.D. Dissertation. Universityof Pennsylvania.
Vilhelm Sjöberg, Chris Casinghino, Ki Yung Ahn, Nathan Collins, Harley D. Eades III, Peng Fu, Garrin
Kimmell, Tim Sheard, Aaron Stump, and Stephanie Weirich. 2012. Irrelevance, Heterogenous Equality,
and Call-by-value Dependent Type Systems. In Fourth workshop on Mathematically Structured Functional
Programming (MSFP ’12) (MSFP ’12). 112–162.
Vilhelm Sjöberg and Stephanie Weirich. 2015. Programming Up to Congruence. In Proceedings of the 42Nd
Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL ’15). ACM,
New York, NY, USA, 369–382. https://doi.org/10.1145/2676726.2676974
Martin Steffen. 1998. Polarized Higher-Order Subtyping. Ph.D. Dissertation. Technische Fakultät, FriedrichAlexander-Universität Erlangen-Nürnberg.
Sandro Stucki. 2017. Higher-Order Subtyping with Type Intervals. Ph.D. Dissertation. EPFL.
Aaron Stump. 2017. The calculus of dependent lambda eliminations. Journal of Functional Programming 27(2017), e14. https://doi.org/10.1017/S0956796817000053
Aaron Stump, Morgan Deters, Adam Petcher, Todd Schiller, and Timothy Simpson. 2008. Verified Programming in Guru. In Proceedings of the 3rd Workshop on Programming Languages Meets Program Verification(PLPV ’09). ACM, New York, NY, USA, 49–58. https://doi.org/10.1145/1481848.1481856
Martin Sulzmann, Manuel M. T. Chakravarty, Simon Peyton Jones, and Kevin Donnelly. 2007. System
F with Type Equality Coercions. In Proceedings of the 2007 ACM SIGPLAN International Workshop on
Types in Languages Design and Implementation (TLDI ’07). ACM, New York, NY, USA, 53–66. https://doi.org/10.1145/1190315.1190324
Nikhil Swamy, Juan Chen, Cédric Fournet, Pierre-Yves Strub, Karthikeyan Bhargavan, and Jean Yang. 2011.
Secure Distributed Programming with Value-dependent Types. In Proceedings of the 16th ACM SIGPLAN
International Conference on Functional Programming (ICFP ’11). ACM, New York, NY, USA, 266–278.
https://doi.org/10.1145/2034773.2034811
Wouter Swierstra. 2008. Data types à la carte. Journal of functional programming 18, 4 (2008), 423–436.
The Coq development team. 2016. The Coq proof assistant reference manual. https://coq.inria.fr/refman/
Version 8.6.
The GHC Team. 2018. The Glasgow Haskell Compiler. https://www.haskell.org/ghc/
The Rust Project Developers. 2011. The Rust Programming Language. https://doc.rust-lang.org/book/
Alan M Turing. 1937. On computable numbers, with an application to the Entscheidungsproblem. Proceedings of the London mathematical society 2, 1 (1937), 230–265.

158

References

L. S. van Benthem Jutting. 1993. Typing in pure type systems. Information and Computation 105, 1 (1993),
30–41.
Floris van Doorn, Herman Geuvers, and Freek Wiedijk. 2013. Explicit Convertibility Proofs in Pure Type
Systems. In Proceedings of the Eighth ACM SIGPLAN International Workshop on Logical Frameworks &Meta-languages: Theory & Practice (LFMTP ’13). ACM, New York, NY, USA, 25–36. https://doi.org/10.
1145/2503887.2503890
Guido van Rossum, Jukka Lehtosalo, and Łukasz Langa. 2014. PEP 484 – Type Hints. https://www.python.
org/dev/peps/pep-0484/
Philip Wadler. 1995. Monads for functional programming. In Advanced Functional Programming, Johan
Jeuring and Erik Meijer (Eds.). Springer Berlin Heidelberg, Berlin, Heidelberg, 24–52.
Stephanie Weirich, Justin Hsu, and Richard A. Eisenberg. 2013. System FC with Explicit Kind Equality. In
Proceedings of the 18th ACM SIGPLAN International Conference on Functional Programming (ICFP ’13).
ACM, New York, NY, USA, 275–286. https://doi.org/10.1145/2500365.2500599
Stephanie Weirich, Antoine Voizard, Pedro Henrique Azevedo de Amorim, and Richard A. Eisenberg. 2017.
A Specification for Dependent Types in Haskell. Proc. ACM Program. Lang. 1, ICFP, Article 31 (Aug.
2017), 29 pages. https://doi.org/10.1145/3110275
Andrew K. Wright and Matthias Felleisen. 1994. A syntactic approach to type soundness. Information andcomputation 115, 1 (1994), 38–94.
Hongwei Xi, Chiyan Chen, and Gang Chen. 2003. Guarded Recursive Datatype Constructors. In Proceedingsof the 30th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL ’03). ACM,
New York, NY, USA, 224–235. https://doi.org/10.1145/604131.604150
Hongwei Xi and Frank Pfenning. 1999. Dependent types in practical programming. In Proceedings ofthe 26th ACM SIGPLAN-SIGACT symposium on Principles of programming languages (POPL ’99). ACM,
214–227.
Yanpeng Yang, Xuan Bi, and Bruno C. d. S. Oliveira. 2016. Unified Syntax with Iso-types. In Programming
Languages and Systems, Atsushi Igarashi (Ed.). Springer International Publishing, Cham, 251–270.
Yanpeng Yang and Bruno C. d. S. Oliveira. 2017. Unifying Typing and Subtyping. Proc. ACM Program. Lang.
1, OOPSLA, Article 47 (Oct. 2017), 26 pages. https://doi.org/10.1145/3133871
Brent A. Yorgey, Stephanie Weirich, Julien Cretin, Simon Peyton Jones, Dimitrios Vytiniotis, and José Pedro
Magalhães. 2012. Giving Haskell a Promotion. In Proceedings of the 8th ACM SIGPLAN Workshop on
Types in Language Design and Implementation (TLDI ’12). ACM, New York, NY, USA, 53–66. https://doi.org/10.1145/2103786.2103795
Jan Zwanenburg. 1999. Pure type systems with subtyping. In TLCA ’99. 381–396.