Crumpets and Gödel's T

Solving problems with new tools makes you better at using your old tools

because brains

Understanding new languages makes you better at your favorite programing languages

A simple but powerful language created in 1958 by Kurt Gödel

How it works

Composed of

  • Natural numbers
  • Functions
  • Variables
  • Primitive recursion
  • ... That's it!

Natural Numbers

enum Nat {
  case Z // 0
  case S(Nat) // 1 + x
}

S(S(S(Z))) // 3

Z // 0

All natural numbers are of type `Nat`

Variables

  • Immutable
  • No assignment
  • Introduced via
    • Functions
    • Primitive Recursor

Functions

Values

λ(x: τ)e

 

where `x` is some variable of some type `τ` and `e` is any expression.

 

// identity function on nats
λ(x: Nat)x

// function application
λ(x: Nat)x(Z) // => Z

Functions

Types

τ1 -> τ2 

 

for any two types τ1 and τ2

 

// takes a Nat, returns a Nat
Nat -> Nat

// takes a (Nat -> Nat), returns a Nat
(Nat -> Nat) -> Nat

Primitive Recursor

A Swift implementation:

func rec<U>(e: Int, e0: U, e1: (Int, U) -> U) -> U {
  if e == 0 { // e = Z
    return e0 // base case
  } else { // e = S(x)
    let x: Int = e - 1 // thus x can be any Nat
    let y: U = rec(x, e0, e1) // result of recursion
    return e1(x, y) // "recursive case"
  }
}
rec e { Z => e0 | S(x) with y => e1 }
// e, e0, e1 are expressions
// x, y are variables
// this is fixed:
//     rec _ { Z => _ | S(_) with _ => _ }

Primitive Recursor

rec e { Z => e0 | S(x) with y => e1 }
// e, e0, e1 are expressions
// x, y are variables
// this is fixed:
//     rec _ { Z => _ | S(_) with _ => _ }

Note that `y` is the result of the recursion

 

`e1` uses `y` but does not make the recursive call

 

Primitive Recursor

Types

rec e { Z => e0 | S(x) with y => e1 }
// e: Nat
// e0: τ
// e1: τ

// x: Nat
// y: τ

Examples

Examples

plus := λ(a: Nat)λ(b: Nat) rec a { Z => b | S(x) with y => S(y) }
plus(0)(1) // =>
plus(Z)(S(Z)) // =>
rec Z { Z => S(Z) | S(x) with y => S(y) } // =>
S(Z) // =>
1
plus(1)(1) // =>
plus(S(Z))(S(Z)) // =>
rec S(Z) { Z => S(Z) | S(x) with y => S(y) } // =>
S(y) // where y = rec Z { Z => S(Z) | S(x) with y => S(y) } =>
S( rec Z { Z => S(Z) | S(x) with y => S(y) } ) // => 
S(S(Z)) // =>
2

Examples

plus := λ(a: Nat)λ(b: Nat) rec a { Z => b | S(x) with y => S(y) } 

Take two numbers

 

Recurse on the first one

When it's zero

 

 

When it's not zero

 

 

0 + b = b // so return b
y = (a-1) + b
// we want "a + b"
(a-1) + b + 1 = y + 1 = S(y)
// so return S(y)

Keep your mind open for new connections!

Crumpets and Godels T

By bkase

Crumpets and Godels T

An introduction

  • 796