sUTL stands for sUTL Universal Transform Language—a recursive acronym—and is pronounced “subtle”.
The idea behind sUTL is that a surprising amount of software can be understood as JSON in, JSON out.
An application receives a request through an API. It calls another service and gets more JSON. It reads a database record and represents that as JSON too. The application combines and transforms those values into two more values: one to store, and one to return.
The networking, database access, authentication, and persistence still belong to the host application. But the decision in the middle is often simply a transformation of structured data.
sUTL was created to make that transformation explicit, portable, and safe to pass between systems.
Software already speaks JSON
Modern systems routinely meet at a common boundary:
- an API request becomes a map of values;
- service responses become maps and arrays;
- database records become maps and arrays;
- configuration and policy are represented as data;
- results are serialized back into the same family of values.
sUTL calls this domain MLSNBN. It is deliberately the same practical domain as JSON.
A host application can therefore gather all the values that a decision needs, hand them to a sUTL evaluator, and receive an ordinary JSON-compatible result. The evaluator does not need access to the network, filesystem, database, or application internals.
The program travels as data
A sUTL transform is itself an MLSNBN value. There is no separate source-code syntax to parse before it can be stored or transmitted.
That means a transform can be:
- sent in an API request;
- stored in a database record;
- embedded in configuration;
- copied between JavaScript, Python, Go, and other host languages;
- inspected, generated, versioned, and compared using ordinary JSON tools;
- combined with other transforms without constructing source-code strings.
Data and program share a representation, but they do not share a role. The host chooses which value is the source and which value is the transform, then passes both to the evaluator.
For example, a JavaScript interface can construct or select a transform and send it with some data to a Python service. The Python service does not execute JavaScript or Python supplied by the client. It evaluates the sUTL transform against the values it has deliberately exposed. Another implementation in another language can perform the same operation.
A small language between large systems
sUTL is not intended to replace the host application. It defines a narrow meeting point between applications.
The host remains responsible for effects:
- receiving requests;
- checking identity and permissions;
- calling APIs;
- reading records;
- choosing the source data exposed to the transform;
- validating and writing the result;
- enforcing time and memory limits.
sUTL is responsible for the pure middle:
collected JSON + sUTL transform + libraries → result JSON
This separation makes the boundary visible. A transform cannot secretly open a socket or update a table because those operations are not part of the language. If an application wants a result written somewhere, it must inspect the returned value and perform that effect itself.
Powerful without ambient authority
sUTL is Turing complete. It supports recursion, higher-order transforms, conditional evaluation, reduction, and libraries written in sUTL itself. The core transform library demonstrates that substantial reusable behaviour can be built without adding host-language primitives.
At the same time, evaluation is side-effect free. A sUTL program receives values and produces a value. It has no ambient authority: no filesystem, no network, no process execution, and no database connection unless a host deliberately changes the model and grants such capabilities.
This makes sUTL suitable as a sandbox for capabilities. Uncontrolled input cannot escape into host-language code merely because it is evaluated as sUTL.
Turing completeness does require a second kind of protection. A pure program can still recurse forever or consume excessive memory. A production evaluator must impose resource limits such as a deadline, instruction or recursion budget, and memory limits. The browser runner on this site evaluates transforms in a disposable Web Worker with a timeout so a non-terminating transform cannot freeze the page.
One transformation, many hosts
The larger goal is interoperability. If several languages implement the same sUTL dialect, they can share executable transformations without sharing a runtime:
JavaScript UI ─┐
Python API ────┼─ JSON values + sUTL ─→ the same transformation model
Go service ────┘
Each host can keep the libraries, frameworks, and deployment model appropriate to its job. sUTL supplies a common, serializable language in the domain they already share.
That was the experiment: if much of application behaviour is transformation over JSON-shaped values, perhaps that behaviour can be made portable data too.