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. \[ \frac{A,B}{A\wedge B}(I_{\wedge})\]

Formation of type \[\frac{A,B:Type}{A\times B:Type}(F_{\times})\]

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

Eliminiation rules in logic, e.g. \[ \frac{A\wedge B}{A}(E_{*\wedge})\] \[\frac{A\wedge B}{B}(E_{\wedge*})\]

Elim/Getters of type \[\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 \[\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. \[ \frac{A,B}{A\wedge B}(I_{\wedge})\]

Formation of type \[\frac{A,B:Type}{A\times B:Type}(F_{\times})\]

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

Elim. logic, e.g. \[ \frac{A\wedge B}{A}(E_{*\wedge})\] \[\frac{A\wedge B}{B}(E_{\wedge*})\]

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

{

Computation \[\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\(\Rightarrow\)Q

Implication LOGIC

Introduction \[ \frac{\Gamma, A\vdash B}{\Gamma \vdash A\Rightarrow B}(I_{\Rightarrow})\]

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

Intro/Constructor of data \[\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 \[\begin{array}{rl} \Gamma &\vdash A\Rightarrow B\\ \Gamma & \vdash A\\ \hline \Gamma & \vdash B\end{array}(E_{\Rightarrow})\]

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

{

Computation/Comprehension \[\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_{\to})\)

\((C_{\to})\)

Implication LOGIC

Introduction \[ \frac{\Gamma, A\vdash B}{\Gamma \vdash A\Rightarrow B}\]

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

Intro/Constructor of data \[\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 \[\begin{array}{rl} \Gamma &\vdash A\Rightarrow B\\ \Gamma & \vdash A\\ \hline \Gamma & \vdash B\end{array}\]

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

{

Computation/Comprehension \[\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_{\to})\)

\((C_{\to})\)

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

> b = myFunc(a)

You the programmer!

(Or a theorem prover)

The computer

Formation of type \[\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 \[\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 \[\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})\]

Computation/Comprehension \[\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 \[\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 \[\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 \[\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})\]

Computation/Comprehension \[\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 \[\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 \[\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 \[\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})\]

Computation/Comprehension \[\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 \[\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 \[\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 \[\begin{array}{rl} f:& A\to B \\ a:& A \\ \hline f(a): & B \end{array}(E_{\to})\]

Computation/Comprehension \[\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 \(\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 \(P\wedge Q\) becomes pairs \(A\times B\)
  • IMPLIES \(P\Rightarrow Q\) becomes functions \(A\to B\)

Function Types

By James Wilson

Function Types

The function type is the natural evolution of logical implication.

  • 72