Introduction
Programs are complicated. How do we develop a better understanding of how they work? Denotational semantics is the subarea of programming languages where people study the behaviors of programs by mapping them into some semantic domain of mathematical objects.
The lambda calculus is one of the simplest programming languages there is. Written in Backus-Naur form (BNF), it only has three kinds of expressions:
which stands for variable, function abstraction, and function application. Despite its simplicity, the lambda calculus is Turing-complete, and in particular can represent infinite loops. There has been interesting work in giving semantics to the lambda calculus via domain theory, but that’s the topic for another day.
Computational trilogy
We will focus our attention on simply typed lambda calculus(STLC). STLC adds types to the (pure) lambda calculus. As a programming language, STLC is strongly normalizing, meaning that every well-typed term will eventually evaluate to a normal form. That shouldn’t be discouraging, since STLC is closely connected to intuitionistic logic, via the Curry-Howard correspondence. It turns out that logic and type systems are both connected to category theory via the so-called Curry-Howard-Lambek correspondence.
The goal of this post is to explicitly spell out a categorical semantics of STLC. I was unable to find proofs for the following table taken from this nlab page on “computational trilogy”, so I figured it will be a fun exercise to spell them out here.
logic | type theory | category theory |
---|---|---|
propositions | types | objects |
proofs | terms | / |
impl-intro | abstraction | counit from tensor-hom adjunction |
impl-elim | application | unit from tensor-hom adjunction |
cut elimination | reduction | zigzag identities |
identity elimination | conversion | other zigzag |
Categorical semantics
Some of the following definitions are adapted from Benjamin Pierce’s Basic Category for Computer Scientists.
The type theory
We define the grammar for types in STLC:
And the grammar for terms:
Here, is the type with one element . we also consider the following typing rules:
Here, the -I and -E refer to introduction rules and elimination rules. Introduction rules describe how to produce terms of a certain type, whereas elimination rules corresponds to how to consume terms of a certain type. We call the syntax associated with them introduction forms and elimination forms. For example, and are introduction forms, whereas , or say , are elimination forms.
A Cartesian-closed category
For the other piece of the translation, we fix any Cartesian-closed category (CCC) . Recall that a Cartesian-closed category is a category with finite products, such that for each object , the right product functor has a right adjoint called the exponential.
The definition of adjunctions come with a unit natural transformation and a counit natural transformation such that the following “zigzag” equalities hold:
Here is the identity functor on , and the caligraphic denotes identity natural transformations on the respective functors.
An alternative formulation of the unit equation is useful as follows. For each object , the component of the unit has the universal property such that, for any and morphism from (the product functor applied to ) to , there exists a unique morphism from to (the exponential functor applied to ) making the diagram commute:
The translation
We are finally ready to define the semantic translation! The double brackets takes something from the type theory and maps it into the CCC we specified. On types, it is defined inductive on the syntax and maps each type to an object in the CCC. Again, the following translations are taken from Pierce’s Basic Category for Computer Scientists:
The translation for the typing context is inductively defined on the number of variables: and .
Finally, we inductively define the translation on the typing derivations:
Derivation | Translation | Domain | Target |
---|---|---|---|
For this particular formulation of STLC, it just so happens that for any fixed context, if a term is typeable then there is a unique typing rule that applies to it. This can be seen just from the fact that each term grammar branch appears in the conclusion of exactly one typing rule. Thus, we can be a little hand-wavy and define the translations on the term syntax directly.
Semantics respects equivalence
-equivalence
-equivalence is about how to reduce expressions to simpler ones. First define a Call-by-value small-step operational semantics:
As we can see, these rules tell us how elimination forms can “eliminate” introduction forms. The notation denotes (capture-avoiding) substitution of free occurences of for inside . And we can denote -equivalence, written , as the reflexive-symmetric-transitive closure of this relation. However, proving that beta equivalence plays well with the semantics is now try because substitution is defined inductively on the syntax!
We will prove the following helpful lemma: If and , then
Proof: Induction on the typing derivation of .
-equivalence
The -equivalence for function types says that for whatever types , a function should be considered “the same” as . Indeed, the latter seems to be just ” with extra steps”. It is an instance of a more general idea called contextual equivalence, or even more abstractly, extensional equivalence. In short, it means that things are identified by “extension”, i.e. how they act from the outside perspective.
One might notice that is an introduction form immediately wrapped around an elimination form, both for arrow types. In general, -equivalences almost all look like this.
-equivalence for product types
This amounts to claiming that , which follows immediately from the universal property of the product:
-equivalence for arrow types
Suppose . Then must be of type , but it doesn’t have to be in normal form. The semantics of the typing derivations defined earlier tells us
Tho a mouthful, is a morphism from to . If we set to be , and as , then the diagram for the unit equation becomes
Where did the mystery come from? Well, since is of the form composed with something, we can just define to be the something, aka , and the above diagram will trivially commute. But, note is actually equal to .
Finally, for the real kicker, we invoke the uniqueness of in the universal property of , so that . Thus,
Conclusion
This was mostly just an exercise for me to make sure that the categorical semantics of STLC is sensible. Indeed, we have verified parts of the analogy from the nlab “computational trilogy” table, that the semantic respects and equivalence. Actually, the proof came down exactly to the unit and counit equations, just as in the table.
Note that our version of STLC doesn’t contain any “ground types” besides . One can simply add more ground types like , etc. The translation will then be incorporated to map each ground type to some designated object in our CCC, and the proof still works because it was defined inductively on the typing derivations. However, in this way the categorical semantics will not be able to enforce fine-grained equational constraints like 40 + 2 = 42
on the operational semantics.
References
- B. C. Pierce, Basic Category Theory for Computer Scientists. The MIT Press, 1991. doi: 10.7551/mitpress/1524.001.0001.
- S. Mac Lane, Categories for the Working Mathematician, vol. 5. in Graduate Texts in Mathematics, vol. 5. New York, NY: Springer, 1978. doi: 10.1007/978-1-4757-4721-8.
- https://ncatlab.org/nlab/show/computational+trilogy
- https://hustmphrrr.github.io/asset/pdf/comp-exam.pdf