Skip to content

Strings

String Literals #

let greeting = "Hello, World!"
let single = "It's a string"

String Interpolation #

Embed expressions inside strings using {}:

let name = "Zolo"
let msg = "Hello, {name}!"          // "Hello, Zolo!"

let x = 10
let y = 20
let sum = "{x} + {y} = {x + y}"    // "10 + 20 = 30"

Expressions in Interpolation #

Any expression can go inside {}:

let items = [1, 2, 3]
print("Count: {Array.len(items)}")      // "Count: 3"
print("Double: {items[0] * 2}")         // "Double: 2"
print("Greeting: {if loud { "HI!" } else { "hi" }}")

Nested Interpolation #

Interpolated expressions can contain their own strings:

let result = "User: {get_user("admin").name}"

Multiline Strings #

Use triple quotes """ for multiline strings:

let text = """
    This is a
    multiline string
    with indentation preserved
"""

Tagged Templates #

Tagged templates let you prefix a string with a tag name, enabling DSL-like syntax:

let id = 42
let query = sql"SELECT * FROM users WHERE id = {id}"

let title = "Hello"
let page = html"<h1>{title}</h1>"

How Tagged Templates Work #

A tagged template tag"text {expr} more" compiles to a function call:

// sql"SELECT * FROM users WHERE id = {id}"
// compiles to:
sql({"SELECT * FROM users WHERE id = ", ""}, id)

The tag function receives:

  1. A table of string literal parts
  2. The interpolated expression values as additional arguments

Defining Tag Functions #

fn sql(parts: [str], id: int) -> str {
    "{parts[0]}{id}{parts[1]}"
}

fn html(parts: [str], content: str) -> str {
    "{parts[0]}{content}{parts[1]}"
}

Plain Tagged Templates #

Tagged templates without interpolation:

let path = raw"C:\Users"    // raw({"C:\\Users"})

Note: re"..." is not a tagged template — it is a dedicated regex literal (see "Regex Literals" below). Use any other tag name for custom tagged-template functions.

Regex Literals #

re"pattern"flags? produces a typed regex value (Type::Regex) backed by the standard regex module. Pattern syntax is validated at compile time — malformed patterns (unclosed (, trailing %, missing [ after %f, …) are rejected by the compiler before any code runs.

Lua pattern classes (%d, %a, %s, …) flow through verbatim; character classes [a-z], anchors ^/$, and quantifiers */+/-/? work as in regex.test.

let pat = re"^[a-z]+$"
pat.test("hello")           // true
pat.test("Hello")           // false — capital
pat.find("greet hello")     // { text: "hello", start: ..., stop: ... }
pat.replace_all("a1b2c3", "%d", "*") // "a*b*c*"

re"%d+".test("answer 42")   // true — anonymous use

Flags #

The flag suffix follows the closing " with no whitespace.

Flag Effect
i Case-insensitive. Each ASCII letter in the pattern is rewritten at compile time so it matches both cases (a[aA], [a-z][a-zA-Z]).
re"hello"i.test("HELLO")    // true
re"[a-z]+"i.test("MixedCase") // true

Methods and field #

The literal evaluates to a value with one field and eight methods. The typeck recognizes only these — accessing any other field is a compile error.

Member Type
pattern str — the (possibly transformed) pattern body
test(s) bool
find(s) any (record-shaped: { text, start, stop, groups } | nil)
find_all(s) [any]
match_str(s) any (matched substring or nil)
replace(s, r) str
replace_all(s, r) str
split(s) [str]
count(s) int

Each method delegates to the corresponding regex.* stdlib function.

String Operations #

The standard library provides string utilities:

// Trimming
string.trim("  hello  ")        // "hello"
string.trim_start("  hello")    // "hello"
string.trim_end("hello  ")      // "hello"

// Checking
string.starts_with("hello", "he")   // true
string.ends_with("hello", "lo")     // true
string.contains("hello", "ell")     // true
string.is_empty("")                 // true

// Transforming
string.split("a,b,c", ",")         // ["a", "b", "c"]
string.replace("hello", "l", "r")  // "herro"
string.chars("hello")              // ["h", "e", "l", "l", "o"]

// Padding
string.pad_start("42", 5, "0")     // "00042"
string.pad_end("hi", 5, ".")       // "hi..."

See Standard Library for the full API.

enespt-br