DTL
1.x
Docs/DTL/Introduction
Open

Reading2 min
Updated2 Aug 2026
Sourcev1/index.mdx

DTL

DTL is a small, embeddable expression and function language written in Go. It is meant to be read by analysts and engineers alike, evaluated safely on input you did not write, and embedded in a host application that supplies the vocabulary of whatever domain it belongs to.

fn classify_temperature(temp: float, unit: string = "celsius") -> string:
    let normalized = if unit == "fahrenheit" then (temp - 32) / 1.8 else temp

    match normalized:
        when < 0    => "freezing"
        when < 15   => "cold"
        when < 25   => "comfortable"
        when < 35   => "warm"
        when >= 35  => "hot"
Note

DTL is the Data Transformation Language. It is general-purpose within that remit: the language supplies the syntax, the types and the pure standard library, and the embedding host supplies the vocabulary of whatever domain it is transforming data for.

Why it exists01

Readable by non-programmers
Python-like layout, no semicolons, and no braces for a simple function.
Powerful for developers
Type annotations, pattern matching, error handling and multi-line logic.
Shareable
Functions have namespaces, versions and stable fully-qualified names.
Composable
Functions call other functions, and expressions embed wherever the host allows.
Safe
No side effects by default, sandboxed execution, with depth and timeout limits.

Where the language stops02

The specification defines the language: its syntax, semantics, type system and pure standard library. It does not define what a DTL program can reach outside the interpreter.

Datastores, HTTP, message buses and anything else of that kind are supplied by the embedding host as registered builtins under its own namespaces. A program that reaches one is using a capability somebody granted it deliberately.

A first function03

The pipe operator chains transformations left to right, which is the feature that keeps a function readable once it does more than one thing.

fn anomaly_score(values: float[], window_size: int = 10) -> float:
    let recent = values | tail(window_size)
    let mean = recent | avg()
    let std = recent | stdev()
    let latest = values | last()

    if std == 0 then 0.0
    else abs(latest - mean) / std

Next04