Blue Note · 2025

Type

Introduction

A type-theoretic substrate is a semantic foundation for computing systems where types are not just annotations, but the core structural units of meaning and action. Instead of treating software as opaque applications, the system represents every capability as a typed term: something that declares what it is, what it accepts, and what it produces.

This gives:

  • user inspectability: you can see what an agent thinks it is doing
  • system predictability: agents can only compose workflows that type-check

This post sketches an early design for such a substrate, built as the semantic core of the Blue Note Computer project.

Types as Terms in a Free Algebra

At the core, types are modeled as terms of a free algebra over a signature Σ\Sigma.

τ::=cf(τ1,,τk)(cconstants, f  is k-ary)\tau ::= c \mid f(\tau_1,\ldots,\tau_k) \quad (c \in \text{constants},\ f\ \text{ is k-ary})

Each type is either a constant (like Unit\mathrm{Unit} or Int\mathrm{Int}) or a constructor applied to child types (like List(Int)\mathrm{List}(\mathrm{Int}) or Function(Int,String)\mathrm{Function}(\mathrm{Int},\mathrm{String})).

They are immutable, purely structural syntax trees. This means they can be:

  • reasoned about structurally
  • unified and substituted safely
  • hashed and stored efficiently

Mapping to Implementation

Here’s how this algebra is implemented in types.py:

from dataclasses import dataclass, field

K_TYPE = "type"

@dataclass(frozen=True)
class Type:
    name: str
    params: tuple['Type', ...]
    metadata: dict = field(default_factory=dict)
    kind: str = K_TYPE

name\text{name} \to symbol in Σ\Sigma

params\text{params} \to child terms

metadata\text{metadata} \to arbitrary annotations (not part of equality)

kind\text{kind} \to implementation tag (also ignored in equality)

frozen=True \to immutability, matching the free-algebra model

Structural Equality & Hashing

Equality is purely structural:

τ=σ    name(τ)=name(σ) i, τi=σi\tau = \sigma \iff \mathrm{name}(\tau)=\mathrm{name}(\sigma) \ \wedge \forall i,\ \tau_i=\sigma_i

Metadata and kind are ignored. Hashing is computed from (name,params)(\text{name}, \text{params}) only, so structurally equal types are guaranteed to hash the same.

Example:

List(Int)=List(Int)\mathrm{List}(\mathrm{Int}) = \mathrm{List}(\mathrm{Int})
List(Int)List(String)\mathrm{List}(\mathrm{Int}) \ne \mathrm{List}(\mathrm{String})

Algebraic Data Types

Classic ADTs are encoded naturally in this system:

List(τ)μX. 1+τ×X\mathrm{List}(\tau) \cong \mu X.\ 1 + \tau \times X
Option(τ)τ+1\mathrm{Option}(\tau) \cong \tau + 1
Tuple(τ1,,τn)τ1××τn\mathrm{Tuple}(\tau_1,\ldots,\tau_n) \cong \tau_1 \times \cdots \times \tau_n
Function(τin,τout)τoutτin\mathrm{Function}(\tau_{in},\tau_{out}) \cong \tau_{out}^{\tau_{in}}
Record(){i:σi}\mathrm{Record}(\ldots) \cong \{\, \ell_i : \sigma_i \}
Variant()i:σi\mathrm{Variant}(\ldots) \cong \langle\, \ell_i : \sigma_i \rangle

These follow standard cartesian closed category semantics: products, sums, and exponentials.

Effects and Top Type

Effects can be modeled monadically:

IO(τ)State(τ×State)+Error\mathrm{IO}(\tau) \cong \mathrm{State} \to (\tau \times \mathrm{State}) + \mathrm{Error}

There’s also a universal top type \top:

τ, τ\forall\, \tau,\ \tau \le \top

Occurs Check and Free Variables

To support unification, we track free type variables:

FV(α)={α}\mathrm{FV}(\alpha) = \{ \alpha \}
FV(f(τ1,,τk))=iFV(τi)\mathrm{FV}(f(\tau_1,\ldots,\tau_k)) = \bigcup_i \mathrm{FV}(\tau_i)
occurs(α,τ,θ)=αFV(θ(τ))\mathrm{occurs}(\alpha, \tau, \theta) = \alpha \in \mathrm{FV}( \theta(\tau) )

This prevents infinite types when solving type equations.

Next: Unification & Inference

The next step is to implement a full unification algorithm: solving τ1=?τ2\tau_1 \stackrel{?}{=} \tau_2 for the most general unifier (MGU) θ\theta.

This will power type inference and reasoning, letting the system plan and compose capabilities safely. Right now, the system already supports structural equality, hashing, and ADT construction.

Why This Matters

This type algebra is the first building block of a new kind of computing system: one where types are the substrate of execution, not just annotations for compilers.

Even if I don’t build a full operating system, this core could be useful for:

  • agentic planning and orchestration
  • AI-native UI composition
  • capability-based kernels
  • safe modular tool systems

If this sort of thing interests you (Programming language theory or Human–Computer Interaction), I’d love to hear from you.