Standard library
Five namespaces ship preloaded. Every one of them is written in DTL, which is the honest test of whether the language is expressive enough to be worth embedding.
None of them reaches outside the interpreter. Anything that does is a builtin the host registered.
system::math01
fn clamp(value: float, min: float, max: float) -> float =>
if value < min then min else if value > max then max else value
fn lerp(a: float, b: float, t: float) -> float =>
a + (b - a) * t
fn normalize(value: float, min: float, max: float) -> float =>
if max == min then 0.0 else (value - min) / (max - min)
fn moving_avg(values: float[], window: int) -> float =>
values | tail(window) | avg()
fn ewma(values: float[], alpha: float = 0.3) -> float:
values | reduce(values | first(), (acc, v) => alpha * v + (1 - alpha) * acc)system::text02
fn slugify(text: string) -> string =>
text | lower() | trim() | replace(" ", "-") | replace("[^a-z0-9-]", "")
fn truncate(text: string, max_len: int, suffix: string = "...") -> string =>
if text | len() <= max_len then text
else (text | substr(0, max_len - (suffix | len()))) ++ suffix
fn extract_number(text: string) -> float =>
text | match_regex("[0-9]+\\.?[0-9]*") | first() | as_float()system::datetime03
fn business_days_between(start: datetime, end: datetime) -> int:
let days = start | diff(end, "days") | as_int()
let weeks = days / 7
let remaining = days % 7
weeks * 5 + (remaining | clamp(0, 5))
fn is_business_day(dt: datetime) -> bool =>
dt | day_of_week() >= 1 && dt | day_of_week() <= 5
fn time_bucket(dt: datetime, interval: string) -> datetime =>
dt | start_of(interval)system::stats04
fn z_score(value: float, values: float[]) -> float:
let mean = values | avg()
let std = values | stdev()
if std == 0 then 0.0
else (value - mean) / std
fn outlier_bounds(values: float[], factor: float = 1.5) -> object:
let q1 = values | percentile(25)
let q3 = values | percentile(75)
let iqr = q3 - q1
return { lower: q1 - factor * iqr, upper: q3 + factor * iqr }
fn correlation(x: float[], y: float[]) -> float:
let n = x | count()
let sum_xy = x | zip(y) | map((a, b) => a * b) | sum()
let sum_x = x | sum()
let sum_y = y | sum()
let sum_x2 = x | map(v => v * v) | sum()
let sum_y2 = y | map(v => v * v) | sum()
(n * sum_xy - sum_x * sum_y) /
sqrt((n * sum_x2 - sum_x * sum_x) * (n * sum_y2 - sum_y * sum_y))system::collections05
fn top_n(values: any[], n: int, key: string = "") -> any[]:
if key == "" then values | sort(desc) | head(n)
else values | sort_by(key, desc) | head(n)
fn histogram(values: float[], bins: int = 10) -> object[]:
let min_val = values | min()
let max_val = values | max()
let bin_width = (max_val - min_val) / bins
values
| map(v => ((v - min_val) / bin_width) | floor() | clamp(0, bins - 1) | as_int())
| group_by(bin => bin)
| map((bin, items) => {
bin: bin,
range_start: min_val + bin * bin_width,
range_end: min_val + (bin + 1) * bin_width,
count: items | count()
})