{"path":"/sutl/why-sutl","content":{"title":"Why sUTL?","summary":"Portable programs expressed as ordinary structured values: the motivation for a pure transformation language.","body":"[sUTL](/sutl) · [Guide](/sutl/guide) · [Reference](/sutl/reference) · [Examples](/sutl/examples)\n\nsUTL stands for **sUTL Universal Transform Language**—a recursive acronym—and\nis pronounced “subtle”.\n\nThe idea behind sUTL is that a surprising amount of software can be understood\nas **JSON in, JSON out**.\n\nAn application receives a request through an API. It calls another service and\ngets more JSON. It reads a database record and represents that as JSON too. The\napplication combines and transforms those values into two more values: one to\nstore, and one to return.\n\nThe networking, database access, authentication, and persistence still belong\nto the host application. But the decision in the middle is often simply a\ntransformation of structured data.\n\nsUTL was created to make that transformation explicit, portable, and safe to\npass between systems.\n\n## Software already speaks JSON\n\nModern systems routinely meet at a common boundary:\n\n1. an API request becomes a map of values;\n2. service responses become maps and arrays;\n3. database records become maps and arrays;\n4. configuration and policy are represented as data;\n5. results are serialized back into the same family of values.\n\nsUTL calls this domain **MLSNBN**. It is\ndeliberately the same practical domain as JSON.\n\nA host application can therefore gather all the values that a decision needs,\nhand them to a sUTL evaluator, and receive an ordinary JSON-compatible result.\nThe evaluator does not need access to the network, filesystem, database, or\napplication internals.\n\n## The program travels as data\n\nA sUTL transform is itself an MLSNBN value. There is no separate source-code syntax to\nparse before it can be stored or transmitted.\n\nThat means a transform can be:\n\n- sent in an API request;\n- stored in a database record;\n- embedded in configuration;\n- copied between JavaScript, Python, Go, and other host languages;\n- inspected, generated, versioned, and compared using ordinary JSON tools;\n- combined with other transforms without constructing source-code strings.\n\nData and program share a representation, but they do not share a role. The\nhost chooses which value is the source and which value is the transform, then\npasses both to the evaluator.\n\nFor example, a JavaScript interface can construct or select a transform and\nsend it with some data to a Python service. The Python service does not execute\nJavaScript or Python supplied by the client. It evaluates the sUTL transform\nagainst the values it has deliberately exposed. Another implementation in\nanother language can perform the same operation.\n\n## A small language between large systems\n\nsUTL is not intended to replace the host application. It defines a narrow\nmeeting point between applications.\n\nThe host remains responsible for effects:\n\n- receiving requests;\n- checking identity and permissions;\n- calling APIs;\n- reading records;\n- choosing the source data exposed to the transform;\n- validating and writing the result;\n- enforcing time and memory limits.\n\nsUTL is responsible for the pure middle:\n\n```text\ncollected JSON + sUTL transform + libraries → result JSON\n```\n\nThis separation makes the boundary visible. A transform cannot secretly open a\nsocket or update a table because those operations are not part of the language.\nIf an application wants a result written somewhere, it must inspect the\nreturned value and perform that effect itself.\n\n## Powerful without ambient authority\n\nsUTL is Turing complete. It supports recursion, higher-order transforms,\nconditional evaluation, reduction, and libraries written in sUTL itself. The\ncore transform library demonstrates that substantial reusable behaviour can be\nbuilt without adding host-language primitives.\n\nAt the same time, evaluation is side-effect free. A sUTL program receives\nvalues and produces a value. It has no ambient authority: no filesystem, no\nnetwork, no process execution, and no database connection unless a host\ndeliberately changes the model and grants such capabilities.\n\nThis makes sUTL suitable as a sandbox **for capabilities**. Uncontrolled input\ncannot escape into host-language code merely because it is evaluated as sUTL.\n\nTuring completeness does require a second kind of protection. A pure program\ncan still recurse forever or consume excessive memory. A production evaluator\nmust impose resource limits such as a deadline, instruction or recursion\nbudget, and memory limits. The browser runner on this site evaluates transforms\nin a disposable Web Worker with a timeout so a non-terminating transform cannot\nfreeze the page.\n\n## One transformation, many hosts\n\nThe larger goal is interoperability. If several languages implement the same\nsUTL dialect, they can share executable transformations without sharing a\nruntime:\n\n```text\nJavaScript UI ─┐\nPython API ────┼─ JSON values + sUTL ─→ the same transformation model\nGo service ────┘\n```\n\nEach host can keep the libraries, frameworks, and deployment model appropriate\nto its job. sUTL supplies a common, serializable language in the domain they\nalready share.\n\nThat was the experiment: if much of application behaviour is transformation\nover JSON-shaped values, perhaps that behaviour can be made portable data too.\n\n## In use today\n\nEverything uses sUTL for bounded programmable templates. The host supplies page data, evaluates the transform under resource limits, then validates and renders the returned layout. See [sUTL in Everything](/sutl/everything).\n\n## Source\n\nAdapted from [the sUTL source material](https://github.com/emlynoregan/sutllang-site/blob/e59ecafd364848cd71a1d18ce74cdf67f2f69328/content/why-sutl.md).\n\n[Back to sUTL](/sutl) · [Software & Agents](/topics/software-and-agents) · [All topics](/guide)","author":"Emlyn O'Regan"}}