Skip to main content

Introduction

Ulexite is a programming language whose central abstraction is the conversation โ€” not the prompt, not the model, not the agent. It compiles conversations involving humans, LLMs, tools, judges, datasets, and multimodal artifacts to a deterministic execution graph, with reproducible traces and first-class testing built into the grammar rather than bolted on as a library.

๐Ÿ’Ž Why "Ulexite"?

Ulexite is a real mineral, nicknamed the "TV rock" โ€” it grows as a bundle of parallel fibers that pipe an image undistorted from one face of the stone to the other. Fitting for a language whose job is carrying a conversation faithfully from one end to the other.

The claimโ€‹

Every mature computing domain eventually gets a language, not just a library:

  • relational data got SQL

  • infrastructure got Terraform/HCL

  • browser automation got Playwright's test runner

  • build graphs got Bazel/Starlark

  • concurrent, fault-tolerant systems got Erlang/Elixir.

In each case, the shift from "a library in a general-purpose language" to "a language with its own grammar, type system, and runtime" happened because the domain had a recurring shape that libraries could approximate but not enforce โ€” and because it needed guarantees (determinism, reproducibility, static checking, a canonical execution model) that a library bolted onto a host language's control flow could never fully deliver.

LLM-driven conversational AI has reached that point. It has a recurring shape: a sequence of turns between typed participants (humans, models, tools, judges), producing typed multimodal artifacts, threaded through automatic history, subject to retries and non-determinism, and increasingly required to be testable, reproducible, and auditable in production.

Today that shape gets approximated by a dozen incompatible Python/TypeScript libraries, each reinventing conversation state, retries, tracing, and evaluation as ad hoc application code โ€” because none of them is a language. None has a grammar that can statically reject an unhandled judge verdict. None has a compiler that can prove a multimodal artifact is being routed to a model that actually accepts it. None has a runtime whose replay guarantee is a language-level contract rather than a best-effort SDK feature.

What Ulexite isโ€‹

Ulexite has a lexer, a parser, static semantic analysis, an intermediate representation, and a runtime โ€” independent of any single LLM provider. Its central value proposition:

The conversation is the unit of compilation and execution. Everything else โ€” models, tools, judges, artifacts, retries, traces โ€” is a typed participant, message, or effect inside that conversation, checked and scheduled by the compiler and runtime, not hand-assembled by application code.

Concretely, that claim is this whole program โ€” a judge, a conversation, and the retry/escalate shape spelled out as grammar rather than glue code:

judge Fluency(subject: text) -> Verdict {
rubric: """Is this an accurate, fluent translation of the source? Answer Pass, Fail(reason), or Escalate if you cannot tell."""
}

conversation Translate(source: text, target_lang: text) -> text {
system: """You are a professional translator."""
user: """Translate to {target_lang}: {source}"""
assistant -> draft: text

match judge Fluency(draft) {
Pass => draft
Fail(reason) => retry(2) {
user: """The previous translation was rejected: {reason}. Try again."""
assistant -> draft
} else escalate(human_approval, reason: reason)
Escalate => escalate(human_approval, reason: "judge could not decide")
Score(_) => draft
}
}

It's closer in spirit to Terraform (declare a graph, preview it, apply it, replay it), Playwright (auto-waiting, tracing, and assertions as language primitives, not test-runner conventions), and Gleam/Elixir (sound typing and supervision as defaults, not opt-in patterns) โ€” applied to conversations with and between intelligent, non-deterministic participants.

What Ulexite is notโ€‹

  • Not a general-purpose language. It has no ambition to write web servers or device drivers. It calls out to a host ecosystem (Python, JavaScript, shell) for anything outside its domain, the way SQL calls out to application code for anything outside relational queries.
  • Not a determinism machine for LLMs. Ulexite doesn't pretend a model call can be made deterministic. It makes the scaffolding around the call โ€” retries, validation, routing, tracing, replay of the deterministic parts of a run โ€” deterministic and typed, while treating the model call itself as an explicitly effectful, explicitly non-deterministic primitive.
  • Not trying to out-optimize DSPy or out-orchestrate LangGraph. Automatic prompt optimization and arbitrary graph topologies are legitimate techniques, and Ulexite's standard library can express versions of both โ€” they're just not the reason the language exists.

Why nowโ€‹

Three things have changed since the current generation of LLM libraries were designed:

  1. Structured output is now a solved backend problem. Grammar-constrained decoding proved token-level constraint enforcement works; the technique is now provider-supported (JSON mode, structured outputs, tool-calling schemas) widely enough that a language can assume typed structured output as a baseline, not a research feature.
  2. Multi-turn, multi-agent, multi-provider is the default case, not the exception. Frameworks like LangGraph and OpenAI's Agents SDK have independently converged on "conversation as a persisted, replayable object" โ€” evidence the industry already wants this, without anyone making it a language-level guarantee instead of an SDK feature.
  3. Evaluation and testing are the operational bottleneck, not the model call. Tools like Promptfoo and OpenAI Evals prove teams want matrix testing, LLM-as-judge grading, and golden datasets โ€” but they remain config-file test runners bolted onto a separate orchestration codebase, rather than a language where expect, judge, and dataset are as native as if and for.

What running it looks likeโ€‹

That same Translate conversation, actually run against a provider โ€” the judge passes it on the first try here; see Getting Started for the retry/escalate path instead:

bash
$ ulx run translate.ulx Translate --arg source=hello --arg target_lang=fr --provider anthropic
๐Ÿงญ system: You are a professional translator.
๐Ÿง‘ user: Translate to fr: hello
๐Ÿค– assistant: Bonjour
โš–๏ธ judge Fluency: Pass
Bonjour
run id3e9a7c1d5f2b8064
statusok
capabilitieschat, judge
provideranthropic โ€” chat (claude-haiku-4-5), judge (claude-sonnet-4-5)
$

Ready to see it in practice? Continue to Getting Started, or jump straight to the Playground to run a conversation against a real local model, live in your browser.


This page adapts ยง1 Vision of the full spec (RFC-0001) โ€” see there for the complete argument, including the prior-art survey and gap analysis this claim is built on.