Every language designed before 2023 was optimized for a single tradeoff: minimize friction between human cognitive capacity and machine execution. Assembly to C to managed runtimes to DSLs were different points on the same line. In an LLM-driven workflow, those languages don’t get cheaper to use — they get more expensive. The cost just hides in the LLM’s token count, its retry rate, and the latency it eats per turn. Pre-LLM languages are a hidden tax in the LLM era.
Most of an LLM’s per-turn effort isn’t recalling syntax. It’s translating between the user’s mental model of a system and the language’s structural shape. A language whose primitives don’t match how the system is thought about forces this translation every turn, paying full cost each time.
Aperio is built on a different premise: there exists a substrate-invariant structural model — a recursive hypergraph of typed, lifecycled units called loci — that both human reasoning and LLM reasoning operationalize when working with systems. A language whose primitives are that model collapses the translation layer. The mental model and the code share a substrate.
Pick a system you already have a mental model for: the matchmaker behind a multiplayer game. In your head, the thing is a service that holds a queue of waiting players, spawns a match when enough are queued, and goes back to waiting.
Here’s that, in Aperio:
type Player { id: String; name: String; } type MatchInfo { match_id: String; players: [Player]; } topic JoinQueue { payload: Player; } topic MatchReady { payload: MatchInfo; } @form(vec) locus Matchmaker { params { target_size: Int = 4; } capacity { heap waiting of Player; } bus { subscribe JoinQueue as on_join; publish MatchReady; } fn on_join(p: Player) { self.waiting.push(p); if self.waiting.len() >= self.target_size { MatchReady <- assemble_match(self.waiting, self.target_size); } } }
Every clause of the mental-model description has a syntactic home in the code, in roughly the order you thought about them:
“a service” → locus Matchmaker
“holds a queue of waiting players” → capacity { heap waiting of Player; } (the @form(vec) annotation gives it queue-like methods)
(the annotation gives it queue-like methods) “receives players wanting matches” → subscribe JoinQueue as on_join
... continue reading