Domain-Specific Languages
When a new language is cheaper than a library, when it is much more expensive, and what the tooling bill actually looks like once people depend on it.
A language restricted to one problem domain, which is what lets it say more with less and refuse to express things the domain considers nonsense. The restriction is the feature; every DSL that grows out of it becomes a general-purpose language with worse tools.
An internal DSL is written in the host language and inherits its entire toolchain for free. An external one has its own syntax and its own parser, and must build every tool from scratch. The choice is almost entirely about who pays for the tooling.
Almost always no. Four questions decide it — is the domain stable, do the readers genuinely need non-host syntax, is the tooling budgeted, and could a library do it — and a yes needs all four. This lesson is the decision, stated as a decision.
Five ways to make a domain language actually run: interpret the tree, compile to the host language, compile to bytecode, generate code at build time, or embed it as schema-validated data. They differ in performance, in debuggability and in who sees the error.
JSON, TOML, YAML, HCL, Jsonnet, Starlark, CUE, Dhall — a ladder from pure data to real computation. Every rung was reached by a format that started as data and was asked for one more feature, and the two that stopped deliberately are the interesting ones.
The parser is a weekend. What people expect the moment they depend on your language — positioned diagnostics, error recovery, a formatter, editor support, a debugging story, documentation, versioning and a migration path — is the project, and it never finishes.