Functions as implications

2025 James B. Wilson

Towards the Curry-Howard isomorphism.

Curry-Howard Isomorphism:

Logic turns into data types

Logical Operator

  • (L)anguage
  • (I)ntroduction
  • (E)limination

Type

  • (F)ormation
  • (I)ntroduction
  • (E)limination
  • (C)omputation

Recap with AND

Introduction rule in logic, e.g. A,BAB(I) \frac{A,B}{A\wedge B}(I_{\wedge})

Formation of type A,B:TypeA×B:Type(F×)\frac{A,B:Type}{A\times B:Type}(F_{\times})

Intro/Constructor of data a:A,b:B(a,b):A×B(I×)\frac{a:A, b:B}{(a,b):A\times B}(I_{\times})

Eliminiation rules in logic, e.g. ABA(E) \frac{A\wedge B}{A}(E_{*\wedge}) ABB(E)\frac{A\wedge B}{B}(E_{\wedge*})

Elim/Getters of type x:A×BgetA(x):A(E×)x:A×BgetB(x):B(E×)\frac{x:A\times B}{get_A(x):A}(E_{*\times})\qquad\frac{x:A\times B}{get_B(x):B}(E_{\times*})

{

Computation/Comprehension a:Ab:BgetA(a,b)=agetB(a,b)=b(C)\begin{array}{rl}a: & A\\ b: & B\\ \hline get_A(a,b) & =a\\ get_B(a,b) & = b\end{array}(C_{\wedge})

{

Recap with AND

Intro. logic, e.g. A,BAB(I) \frac{A,B}{A\wedge B}(I_{\wedge})

Formation of type A,B:TypeA×B:Type(F×)\frac{A,B:Type}{A\times B:Type}(F_{\times})

Intro/Constructor of data a:A,b:B(a,b):A×B(I×)\frac{a:A, b:B}{(a,b):A\times B}(I_{\times})

Elim. logic, e.g. ABA(E) \frac{A\wedge B}{A}(E_{*\wedge}) ABB(E)\frac{A\wedge B}{B}(E_{\wedge*})

Elim/Getters of type x:A×BgetA(x):AgetB(x):B(E×)\begin{array}{rl} x:&A\times B\\ \hline get_A(x): & A\\ get_B(x):& B \end{array}(E_{\times})

{

Computation a:Ab:BgetA(a,b)=agetB(a,b)=b(C)\begin{array}{rl}a: & A\\ b: & B\\ \hline get_A(a,b) & =a\\ get_B(a,b) & = b\end{array}(C_{\wedge})

{

Text

import ctx;

class Pair[A,B]
  
  makePair(a:A, b:B) {
    myA = a; myB = b
  }
  
  getA():A { return myA }
  getB():B { return myB }
  
> x = new Pair("five", 5)
> x.getA()
five
> x.getB()
5

Curry-Howard Isomorphism for Implies P\RightarrowQ

Implication LOGIC

Introduction Γ,ABΓAB(I) \frac{\Gamma, A\vdash B}{\Gamma \vdash A\Rightarrow B}(I_{\Rightarrow})

Formation of type A,B:TypeAB:Type(F)\frac{A,B:Type}{A\to B:Type}(F_{\to})

Intro/Constructor of data Φ:Stringx:Variableproof:(a:AΦx:=a:B)(xΦ):AB\begin{array}{rl} \Phi: & \text{String}\\ x: & \text{Variable} \\ proof:& (a:A \vdash \Phi|_{x:=a}:B)\\ \hline (x\mapsto \Phi):&A\to B\end{array}

Eliminiation ΓABΓAΓB(E)\begin{array}{rl} \Gamma &\vdash A\Rightarrow B\\ \Gamma & \vdash A\\ \hline \Gamma & \vdash B\end{array}(E_{\Rightarrow})

Elim/APPLY f:ABa:Af(a):B(E)\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})

{

Computation/Comprehension Φ:Stringx:Variableproof:(a:AΦx:=a:B)a:Af(a) =Φx:=a\begin{array}{rl}\Phi: & \text{String}\\ x:&\text{Variable}\\ proof:& (a:A\vdash \Phi|_{x:=a}:B)\\ a: & A\\ \hline f(a)  & = \Phi|_{x:=a}\end{array}

{

(I)(I_{\to})

(C)(C_{\to})

Implication LOGIC

Introduction Γ,ABΓAB \frac{\Gamma, A\vdash B}{\Gamma \vdash A\Rightarrow B}

Formation of type A,B:TypeAB:Type(F)\frac{A,B:Type}{A\to B:Type}(F_{\to})

Intro/Constructor of data prog:Stringx:Variableproof:(a:Aprogx:=a:B)(xprog):AB\begin{array}{rl} \text{prog}: & \text{String}\\ x: & \text{Variable} \\ proof:& (a:A \vdash \text{prog}|_{x:=a}:B)\\ \hline (x\mapsto \text{prog}):&A\to B\end{array}

Eliminiation ΓABΓAΓB\begin{array}{rl} \Gamma &\vdash A\Rightarrow B\\ \Gamma & \vdash A\\ \hline \Gamma & \vdash B\end{array}

Elim/APPLY f:ABa:Af(a):B(E)\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})

{

Computation/Comprehension prog:Stringx:Variableproof:(a:Aprogx:=a:B)a:Af(a) =progx:=a\begin{array}{rl}\text{prog}: & \text{String}\\ x:&\text{Variable}\\ proof:& (a:A\vdash \text{prog}|_{x:=a}:B)\\ a: & A\\ \hline f(a)  & = \text{prog}|_{x:=a}\end{array}

{

(I)(I_{\to})

(C)(C_{\to})

def myFunc(x:A):B {
  program 
     ... x ... 
}

> b = myFunc(a)

You the programmer!

(Or a theorem prover)

The computer

Formation of type A,B:TypeAB:Type(F)\frac{A,B:Type}{A\to B:Type}(F_{\to})

public class MyFunction {
  String myFunc(int x) {
      return "I saw engine number " + x;
  }
  
  public static void main(String[] args) {
	MyFunction f = new MyFunction();
    System.out.println(5);
  }
}

Intro/Constructor of data prog:Stringx:Variableproof:(a:Aprogx:=a:B)(xprog):AB\begin{array}{rl} \text{prog}: & \text{String}\\ x: & \text{Variable} \\ proof:& (a:A \vdash \text{prog}|_{x:=a}:B)\\ \hline (x\mapsto \text{prog}):&A\to B\end{array}

Elim/APPLY f:ABa:Af(a):B(E)\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})

Computation/Comprehension prog:Stringx:Variableproof:(a:Aprogx:=a:B)a:Af(a) =progx:=a\begin{array}{rl}\text{prog}: & \text{String}\\ x:&\text{Variable}\\ proof:& (a:A\vdash \text{prog}|_{x:=a}:B)\\ a: & A\\ \hline f(a)  & = \text{prog}|_{x:=a}\end{array}

Try it yourself (Java)

Visit: https://www.jdoodle.com/online-java-compiler

Formation of type A,B:TypeAB:Type(F)\frac{A,B:Type}{A\to B:Type}(F_{\to})

def myFunc(x:Int):String =
   "I saw engine number " + x

print(myFunc(5))

Intro/Constructor of data prog:Stringx:Variableproof:(a:Aprogx:=a:B)(xprog):AB\begin{array}{rl} \text{prog}: & \text{String}\\ x: & \text{Variable} \\ proof:& (a:A \vdash \text{prog}|_{x:=a}:B)\\ \hline (x\mapsto \text{prog}):&A\to B\end{array}

Elim/APPLY f:ABa:Af(a):B(E)\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})

Computation/Comprehension prog:Stringx:Variableproof:(a:Aprogx:=a:B)a:Af(a) =progx:=a\begin{array}{rl}\text{prog}: & \text{String}\\ x:&\text{Variable}\\ proof:& (a:A\vdash \text{prog}|_{x:=a}:B)\\ a: & A\\ \hline f(a)  & = \text{prog}|_{x:=a}\end{array}

Try it yourself (Scala)

Visit: https://scastie.scala-lang.org/

Formation of type A,B:TypeAB:Type(F)\frac{A,B:Type}{A\to B:Type}(F_{\to})

module Main where

myFunc :: Int -> String
myFunc x = "I saw engine number " ++ show x

main = print (myFunc 5)

Intro/Constructor of data prog:Stringx:Variableproof:(a:Aprogx:=a:B)(xprog):AB\begin{array}{rl} \text{prog}: & \text{String}\\ x: & \text{Variable} \\ proof:& (a:A \vdash \text{prog}|_{x:=a}:B)\\ \hline (x\mapsto \text{prog}):&A\to B\end{array}

Elim/APPLY f:ABa:Af(a):B(E)\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})

Computation/Comprehension prog:Stringx:Variableproof:(a:Aprogx:=a:B)a:Af(a) =progx:=a\begin{array}{rl}\text{prog}: & \text{String}\\ x:&\text{Variable}\\ proof:& (a:A\vdash \text{prog}|_{x:=a}:B)\\ a: & A\\ \hline f(a)  & = \text{prog}|_{x:=a}\end{array}

Try it yourself (Haskell)

Visit: https://replit.com/

Formation of type A,B:TypeAB:Type(F)\frac{A,B:Type}{A\to B:Type}(F_{\to})

# Give me an integer x
# My function will return a poem.
def myFunc(x):
    return "I saw engine number " + str(x)

> myFunc(5)
I saw engine number 5

Intro/Constructor of data prog:Stringx:Variableproof:(a:Aprogx:=a:B)(xprog):AB\begin{array}{rl} \text{prog}: & \text{String}\\ x: & \text{Variable} \\ proof:& (a:A \vdash \text{prog}|_{x:=a}:B)\\ \hline (x\mapsto \text{prog}):&A\to B\end{array}

Elim/APPLY f:ABa:Af(a):B(E)\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})

Computation/Comprehension prog:Stringx:Variableproof:(a:Aprogx:=a:B)a:Af(a) =progx:=a\begin{array}{rl}\text{prog}: & \text{String}\\ x:&\text{Variable}\\ proof:& (a:A\vdash \text{prog}|_{x:=a}:B)\\ a: & A\\ \hline f(a)  & = \text{prog}|_{x:=a}\end{array}

Try it yourself (Python)

Visit: https://replit.com/

Side effects form context

message = "I saw engine number "
# # Give me an integer x
# My function will return a poem.
def myFunc(x):
    return message + str(x)

> myFunc(5)
I saw engine number 5

In all programs we have context which gives more data that you may realize

This data is a constant, but from where?

The context of the function!

Nearly all functions have implicit context,

in fact logic predicts this Γ,PQ\Gamma,P\Rightarrow Q

Side-effects

  • Information used in a function that comes from context is called a side-effect.
  • Can't fully eliminate but you can often make implicit context explicit.
# Give me a message and an integer x
# My function will return a poem.
def myFunc(message, x):
    return message + str(x)

> myFunc("My favorite number is ", 5)
My favorite number is 5

Curry-Howard for simple logic

  • AND PQP\wedge Q becomes pairs A×BA\times B
  • IMPLIES PQP\Rightarrow Q becomes functions ABA\to B