For most of my schooling (basic school, high school), I’ve had a private math teacher thanks to my parents. I believe this has shaped my career path for the better.
I’ve always wanted to be a programmer, and I used to be interested in nothing else. Now I am lucky for the past years to be doing exactly what I’ve always wanted, and that is programming.
Back in basic school, I remember one thing that one of my math teachers kept reminding me: “Study math, it is very closely related to programming”. Now I think I really understand what that statement means.
In any case, I’ve recently started digging into Lean Theorem Prover by Microsoft Research. Having some Haskell experience, and experience with mathematical proofs, the tutorial is mostly easy to follow.
I don’t have much experience with type theory, but I do know some stuff about types from playing with Haskell. I’ve heard about the Curry-Howard correspondence a bunch of times, and it kind of made sense, but I haven’t really understood it in depth. So, by following the Lean tutorial, I got to get introduced to it.
An excerpt from Wikipedia:
In programming language theory and proof theory, the Curry–Howard correspondence (also known as the Curry–Howard isomorphism or equivalence, or the proofs-as-programs and propositions- or formulae-as-types interpretation) is the direct relationship between computer programs and mathematical proofs.
In simpler words, a proof is a program, and the formula it proves is the type for the program.
Now as an example, consider your neat function of swapping 2 values of a product type:
swap :: (a, b) -> (b, a) swap (a, b) = (b, a)
What the Curry-Howard correspondence says is that this has an equivalent form of a mathematical proof.
Although it may not be immediately obvious, think about the following proof:
Given P and Q, prove that Q and P.
What you do next is use and-introduction and and-elimination to prove this.
How does this proof relate to the swap code above? To answer that, we can now consider these theorems within Lean:
variables p q : Prop theorem and_comm : p ∧ q → q ∧ p := fun hpq, and.intro (and.elim_right hpq) (and.elim_left hpq) variables a b : Type theorem swap (hab : prod a b) : (prod b a) := prod.mk hab.2 hab.1
Lean is so awesome it has this
#check command that can tell us the complete types:
#check and_comm -- and_comm : ∀ (p q : Prop), p ∧ q → q ∧ p #check swap -- swap : Π (a b : Type), a × b → b × a
Now the shapes are apparent.
We now see the following:
and.introis equivalent to
prod.mk(making a product)
and.elim_leftis equivalent to the first element of the product type
and.elim_rightis equivalent to the second element of the product type
- forall is equivalent to the dependent type pi-type
A dependent type is a type whose definition depends on parameters. For example, consider the polymorphic type List a. This type depends on the value of a. So List Int is a well defined type, or List Bool is another example.
More formally, if we’re given
A : Typeand
B : A -> Type, then B is a set of types over A.
That is, B contains all types
B afor each
a : A.
We denote it as
Pi a : A, B a.
As a conclusion, it’s interesting how logical AND being commutative is isomorphic to a product type swap function, right? 🙂