Types, Programs, & Categories
2023 James B. Wilson
Colorado State University
class Pair<A,B> {
A myA;
B myB;
Pair(A a, B b) { myA = a; myB = b;}
A piA() { return myA; }
B piB() { return myB; }
}
Math
Programming
Logic
class Pair<A,B> {
A myA;
B myB;
Pair(A a, B b) { myA = a; myB = b;}
A piA() { return myA; }
B piB() { return myB; }
}
Knowing one of these?
Heard of a connection to the others?
Math
Logic
Programming
Three Steps to a Program
- Reason about flow
- Annotate the data
- Match to Programming Idioms
Starting Point: reasoning
Conjunction:
-
context \(\Gamma\) (also
ctx
) says events A and B hold; - Make a single combined event
Simplification:
- Given a conjoined event
- Extract a constituent
Translate to symbols
"Logic"
Mid Point: make it data
Pair:
-
context \(\Gamma\) (also
ctx
) says data \(a\) of type \(A\) and \(b\) of type \(B\); - Make a single paired datum.
Projection:
- Given a paired datum
- Extract a constituent
Get paid more...
Formation
Introduction
Elimination
Computation
Final Point: make it code
Formation
import ctx;
class Pair<A,B> {
...
}
Keyword for "formation"
Parameters to formation rule
Text version of \(\times\) and prefix notation because of language rules.
Context = "import packages"
Final Point: make it code
Formation
Introduction
class Pair<A,B> {
Pair(A a, B b) { ... }
}
Method with no return type signals "Introduction"
I.e. making new data somewhere
Will invoke this with
new Pair(...)
Parameters to introduction rule
Final Point: make it code
Formation
Introduction
class Pair<A,B> {
Pair(A a, B b) { ... }
A piA() { ... }
B piB() { ... }
}
Elimination for B.
Elimination for A
Elimination
Final Point: make it code
Formation
Introduction
class Pair<A,B> {
A myA; B myB;
Pair(A a, B b) {
myA = A; myB=b;
}
A piA() { return myA; }
B piB() { return myB; }
}
Retrieve b from storage when asked
Internally store a.
Elimination
Computation
TRY IT YOURSELF!
Try this right now in
-
Java
-
Scala
-
Haskell
(All you need is a web browser.)
class Pair<A,B> {
A a; B b;
Pair(A a, B b) {
this.a = a;
this.b = b;
}
A piA() { return a; }
B piB() { return b; }
}
public class TrialRun {
// A way to try the code out
public static void main(String args[]) {
Pair<String,Integer> p = new Pair("5",5);
System.out.println("Type " + p.piA().getClass());
System.out.println("Type " + p.piB().getClass());
}
}
Try it! (Java Edition)
Visit https://www.jdoodle.com/online-java-compiler/
Or us VS Code with your personal Java install
class Pair[A,B](a:A, b:B) {
def getA():A = a
def getB():B = b
}
val p:Pair[String,Int] = new Pair("5",5)
val a:String = p.getA()
val b:Int = p.getB()
Try it! (Scala Edition)
Visit https://scastie.scala-lang.org/
Or us VS Code with your personal Scala install
In Scala, formation and introduction can be merged together to make a concise program (but less obvious)
module Main where
data Pair a b = Pair {
x::a,
y::b
}
main = print (y p)
where
p = Pair "5" 5
Try it! (Haskell Edition)
Visit https://replit.com/
Or us VS Code with your personal Haskall install
Haskell prefer \(\sin x\) style to \(\sin(x)\).
Pair a b
means Pair(a,b);
Pair "5" 5
is Pair("5",5).
Also Haskell requires lower case for generic type names, i.e. a not A.
(y p) is Haskell for p.y
Lets Do Better
- Version one of a program is the best you can do.
- Version two is the best you can steal.
Starting Point: reasoning
Conjunction:
-
context \(\Gamma\) (also
ctx
) says events A and B hold; - Make a single combined event
Simplification:
- Given a conjoined event
- Extract a constituent
Translate to symbols
"Logic"
Starting Point: reasoning with reality
Sources:
-
context \(\Gamma\) (also
ctx
) says information from A and B;
Outcomes:
- Combine info.
- Recover individuals
Translate to flow
"Categories"
Comparison:
- How would other solution look at granular scale?
Master the Competition:
- Invent a translation of their's to our's.
Mid Point: make it data
Formation
Introduction
Elimination
Computation
Final Point: make it code
Formation
Introduction
Elimination
Computation
import ctx;
class Pair[A,B,T] (...) {
...
}
import ctx;
class Pair[A,B,T](...) {
def piA():A = ...
def piB():B = ...
}
import ctx;
class Pair[A,B,T](
t:T,
f:T=>A,
g:T=>B) {
def piA():A = ...
def piB():B = ...
}
import ctx;
class Pair[A,B,T](
t:T,
f:T=>A,
g:T=>B) {
def piA():A = f(t)
def piB():B = g(t)
}
Quiz
Mathematics
Program
class IntMod<int n> {
int x;
IntMod(int a) { x = a % n; }
int residue() { return x; }
}
\[\frac{n:\mathbb{Z}}{\mathbb{Z}/n :type} (F_{mod})\]
\[\frac{a:\mathbb{Z}}{[a]:\mathbb{Z}/n} (I_{mod})\]
\[\frac{x:\mathbb{Z}/n}{res(x):\mathbb{Z}} (E_{mod})\]
\[\frac{a:\mathbb{Z}}{ rep([a])\equiv a\pmod{n}} (C_{mod})\]
\[\frac{a:\mathbb{Z}}{prf:rep([a])<n} (C_{mod})\]
\[\frac{a:\mathbb{Z}}{prf:0\leq rep([a])} (C_{mod})\]
Mathematics:
Program
class LessThan<int n> {
.
.
.
}
\[\frac{n:\mathbb{Z}}{[n] :type} (F_{<n})\]
\[\begin{array}{l} a:\mathbb{Z}, b:\mathbb{N}\\ pf:a+b+1=_{\mathbb{Z}}n\\ \hline fin(a,b):[n]\end{array} (I_{<n})\]
\[\frac{p:[n]}{rep(p):\mathbb{Z}} (E_{<n})\]
\[\frac{a:\mathbb{Z}}{ rep(fin(a,b))=a} (C_{<n})\]
class LessThan<int n> {
// uint = unsigned int (non-negative)
// Eq[x,y] type of evidence for x==y
LessThan(int a,uint b,Eq[a+b+1,n] proof){
.
.
.
}
}
class LessThan<int n> {
LessThan(int a,uint b,Eq[a+b+1,n] proof){
.
.
.
}
int rep() { ... }
}
class LessThan<int n> {
int x; // Java has no unit or "Eq" type, improvise
LessThan(int a,int b) {
if (b >= 0) && ( (a+b+1) == n ) {
x = a;
} else {
throw new IllegalArgumentException();
}
}
int rep() { return x; }
}
Make \([n]=\{0,\ldots,n-1\}\)
Final Thoughts
- Program languages (PL) add rules beyond your FIEC.
- Some intro/elim rules ergonomic with idioms
- pattern matching,
- let/where clauses,
- apply/unapply,
- getters/setters,
- polymorphism by hierarchy "extends"
- Some Math too subtle for average PLs.
- Some Math provably undecidable (unprogrammable).
Turing Machine
= Universal Computer
Type Theory
= Universal Programming Language
Types & Programs
By James Wilson
Types & Programs
Demonstration of mathematical types and programming comparables.
- 476