Technology1 min read

Arrows to arrows, categories to queries (2025)

By · Published by Everything Blog

In short

The catlang programming language translates code featuring arrow notation and loops into an algebraic intermediate layer based on category theory. Each abstract symbol in this intermediate representation corresponds to a distinct operation, such as the chaining of execution results. To test the practical capabilities of this categorical design, the compiler targets Postgres by generating a single large SELECT statement. This allows the relational database engine to execute advanced programming structures, including recursive constructs and unions.

Key points

  • SQL serves as an experimental target to prove category theory works as an intermediate la…: SQL serves as an experimental target to prove category theory works as an intermediate language.
  • Relational database engines can run general-purpose program logic through generated queri…: Relational database engines can run general-purpose program logic through generated queries containing unions and recursion.
  • The categorical intermediate representation allows mathematical operations to be mapped t…: The categorical intermediate representation allows mathematical operations to be mapped to external execution environments.

Sources checked by our analysis pipeline: 1

Arrows to Arrows, Categories to Queries

I’ve had a little time off of work as of late, and been spending it in characteristically unwise ways. In particular, I’ve written a little programming language that compiles to SQL. I call it catlang. That’s not to say that I’ve written a new query language. It’s a programming language, whose compiler spits out one giant SELECT

statement. When you run that query in postgres, you get the output of your program.

Why have I done this? Because I needed a funny compilation target to test out the actual features of the language, which is that its intermediary language is a bunch of abstract category theory nonsense. Which I’ll get to. But I’m sure you first want to see this bad boy in action.

Behold, the function that returns 100 regardless of what input you give it. But it does it with the equivalent of a while loop:

: Int -> Int

count =

count ->

x

loop x->

i <- join id id -< i

n <- abs . (-) -< (n, 100)

Technology