Type checking, conversion, and built-in type constructors.

Functions

err core

fn (value: Any): Result

Wrap value in an error Result.Err variant.

Payload convention: use a plain Str for simple errors, or a Map with a message field (plus any structured fields like code) for rich errors. The auto-unwrap halt and err-message both read message (falling back to msg, then the payload itself), so following the convention keeps error text intact end to end.

Example

err("Not found")                          // simple
err({message: "Not found", code: 404})    // structured

if(is-null(user), err("User not found"), ok(user))

err-message core

fn (lazy result: Any): Str

Extract a human-readable message from an error, without re-triggering it. Accepts a Result.Err or a bare payload; understands the payload convention (message field, msg on halt Failure payloads, reason), and falls back to the payload's string form.

Example

err-message(err("connection refused"))              // "connection refused"
err-message(err({message: "pg: bad", code: "42"}))  // "pg: bad"

r ::pg/connect(opts)
if-err(r, (e) { log(`db down: ${err-message(e)}`) })

err-value core

fn (lazy result: Any): Any

Extract the payload of a Result.Err, without re-triggering the error. Returns null for Result.Ok and plain values.

Example

result read-file("missing.txt")
if(is-err(result), println(`failed: ${err-value(result)}`), null)

err-value(err("boom"))   // "boom"
err-value(ok(42))        // null

if-err core

fn (lazy result, handler)

If result is Err, apply function or use value. If Ok, pass through unchanged.

When the second argument is a function, it's called with the Err value. When it's a plain value, it replaces the Err (recovering to Ok).

Example

err("bad") |> if-err("default")
// Ok("default") — recovers with default value

err("bad") |> if-err(err(\`wrapped: ${%}\`))
// Err("wrapped: bad") — transforms the error

err("bad") |> if-err((e) { fetch-backup() })
// Ok(...) or Err(...) — recovery attempt

ok(42) |> if-err("default")
// Ok(42) — passes through unchanged

if-ok core

fn (lazy result, handler)

If result is Ok, apply function or use value. If Err, pass through unchanged.

When the second argument is a function, it's called with the Ok value. When it's a plain value, it replaces the Ok value.

Example

ok(1) |> if-ok(add(%, 10))
// Ok(11)

ok(1) |> if-ok("replaced")
// Ok("replaced")

err("bad") |> if-ok(add(%, 10))
// Err("bad") — passes through unchanged

is-any core

fn (value: Any): Bool

Return true if value is Any (always true).

Example

is-any("anything")  // true
is-any(null)        // true

is-bool core

fn (value: Any): Bool

Return true if value is a Bool.

Example

is-bool(true)   // true
is-bool(false)  // true
is-bool(1)      // false

is-byte core

fn (value: Any): Bool

Return true if value is a Byte.

Example

is-byte(255)  // depends on context

is-bytes core

fn (value: Any): Bool

Return true if value is a Bytes.

Example

data read-file-bytes("file.bin")
is-bytes(data)  // true

is-dec core

fn (value: Any): Bool

Return true if value is a Dec.

Example

is-dec(3.14)   // true
is-dec(42)     // false (Int, not Dec)

is-err core

fn (lazy result: Any): Bool

Return true if result is an error.

Example

is-err(Result.Err("failed"))    // true
is-err(Result.Ok(42))           // false

result fetch-data()
if-err(result, (error) { println(error) })

is-fn core

fn (value: Any): Bool

Return true if value is a Fn.

Example

is-fn(::hot::math/add)  // true
is-fn("add")            // false
is-fn(%)                 // true (lambda)

is-int core

fn (value: Any): Bool

Return true if value is an Int.

Example

is-int(42)     // true
is-int(3.14)   // false
is-int("42")   // false

is-map core

fn (value: Any): Bool

Return true if value is a Map.

Example

is-map({"a": 1})  // true
is-map({})        // true
is-map([1, 2])    // false

is-namespace core

fn (value: Any): Bool

Return true if value is a Namespace.

Example

is-namespace(Namespace("::hot::str"))  // true

is-null core

fn (value: Any): Bool

Return true if value is Null.

Example

is-null(null)    // true
is-null(false)   // false
is-null("")      // false

is-ok core

fn (lazy result: Any): Bool

Return true if result is ok (has a success value).

Example

is-ok(Result.Ok(42))            // true
is-ok(Result.Err("failed"))     // false

result safe-divide(10, 2)
if(is-ok(result), ok-value(result), 0)

is-result core

fn (lazy value: Any): Bool

Return true if value is a Result type.

Example

is-result(ok(42))        // true
is-result(err("fail"))   // true
is-result(42)            // false

is-some core

fn (value: Any): Bool

Return true if value is not Null.

Example

is-some("hello")  // true
is-some(0)        // true
is-some(null)     // false

is-str core

fn (value: Any): Bool

Return true if value is a Str.

Example

is-str("hello")  // true
is-str(42)       // false

is-type core

fn (lazy val, type-ref)

Return true if value conforms to type-ref.

Example

is-type("hello", Str)  // true
is-type(42, Int)        // true
is-type([1, 2], Vec)    // true
is-type("hello", Int)  // false

// Works with pipes
my-value |> is-type(Str)

For custom types, use is-type with the type name:

Point type { x: Int, y: Int }
p Point({x: 1, y: 2})
is-type(p, Point)  // true

Works with Result types without triggering auto-unwrap:

result err("oops")
is-type(result, Result)  // true

is-var core

fn (value: Any): Bool

Return true if value is a Var.

Note: Var references are dereferenced when passed as regular arguments, so this returns true only for Var values reaching it through lazy or metadata contexts.

Example

is-var("::hot::str/split")  // false — a plain string

is-vec core

fn (value: Any): Bool

Return true if value is a Vec.

Example

is-vec([1, 2, 3])  // true
is-vec([])         // true
is-vec({"a": 1})   // false

ok core

fn (value: Any): Result

Wrap value in a successful Result.Ok variant.

Example

ok(42)           // Result.Ok(42)
ok("success")    // Result.Ok("success")

result ok(get-user(id))
user ok-value(result)

ok-value core

fn (lazy result: Any): Any

Extract the payload of a Result.Ok. Plain (non-Result) values are returned unchanged, matching is-ok treating them as successes. Returns null for Result.Err.

Example

ok-value(ok(42))        // 42
ok-value(42)            // 42
ok-value(err("fail"))   // null

untype core

fn (form: Any): Any

Transform Hot typed structures to simple Val structures by removing internal type metadata.

Example

// Given a typed structure
user User({"name": "Alice"})

// Remove type wrapper
untype(user)  // {"name": "Alice"}

Types

All core

All type {
    value: Vec | Map
}

Marker type for values that intentionally represent "all" produced results from a flow.

In normal Hot code you should usually not need to construct All directly. Flow result annotations such as : All<Vec> and : All<Map> are compile-time result-shape directives: they tell the compiler to collect all produced results, then erase to the underlying Vec or Map value at runtime.

Bare All is only accepted on natural collect-all flows (parallel, cond-all, and match-all). Use explicit All<Vec> or All<Map> on serial, pipe, cond, and match.

Any non-All annotation on a collect-all flow states the type of a single result: the flow opts out of collection and returns only the final produced value.

winner: Str cond-all {
    gt(score, 90) => a { "gold" }
    gt(score, 50) => b { "silver" }
}
// winner is the final matching branch's Str, not a collection

Use the All constructor only when you explicitly want to tag a collection value as "all results" for metadata, debugging, or API boundaries:

tagged All({value: [1, 2, 3]})
tagged.value  // [1, 2, 3]

For ordinary flow results, prefer annotation syntax instead:

results: All<Map> parallel {
    a fetch-a()
    b fetch-b()
}

// `results` behaves as the collected Map in normal use.

Any core

fn (value: Any): Any

Any type. Accepts any value (no type constraint).

Example

// Any is used in function signatures to accept any type
process fn (value: Any): Str { Str(value) }

Bool core

fn (value: Any): Bool

Boolean type. Strictly parses boolean-like values: numbers (0 is false, anything else true), the strings "true"/"yes"/"1" and "false"/"no"/"0" (case-insensitive), and null (false). Other strings — including the empty string — are an error, never silently false. Use is-truthy for truthiness checks, or define a Str -> Bool coercion in your namespace for app-specific parsing (e.g. "on"/"off").

Example

Bool(1)         // true
Bool(0)         // false
Bool("true")    // true
Bool("no")      // false
Bool(null)      // false
Bool("hi")      // Err — not a boolean-like string
is-truthy("hi") // true

Byte core

fn (value: Byte): Byte

Single byte type (0-255).

Example

b Byte(65)   // ASCII 'A'
Int(b)       // 65

Bytes core

fn (value: Bytes): Bytes

Byte array type for binary data.

Example

data Bytes([72, 105])  // "Hi" as bytes
::hot::base64/encode(data)  // "SGk="

Dec core

fn (value: Int | Dec): Dec

Decimal type (256-bit precision). Converts numeric values and numeric strings to decimal.

Example

Dec(42)         // 42 (as Dec)
Dec("3.14159")  // 3.14159
div(Dec(1), 3)  // 0.333... (high precision)

Fn core

fn (value: Str | Fn): Fn

Function reference type.

Example

f Fn("add")    // Reference to add function
f(1, 2)         // 3

Int core

fn (value: Int | Dec): Int

Integer type. Convert numeric values to integer (truncates decimals).

Example

Int(42)      // 42
Int(3.7)     // 3
Int(-2.9)    // -2

Map core

fn (value: Any, rest: Any): Map

Map (object) type. With one Vec argument, builds a map from [key, value] pairs and/or single-entry maps. With multiple arguments, treats them as alternating key-value pairs.

Example

Map([["a", 1], ["b", 2]])     // {a: 1, b: 2} — from pairs
Map([{a: 1}, {b: 2}])         // {a: 1, b: 2} — from entry maps
Map("a", 1, "b", 2)           // {a: 1, b: 2} — flat pairs
zipmap(["a", "b"], [1, 2])    // {a: 1, b: 2} — separate key/value vecs

Namespace core

fn (value: Str | Namespace): Namespace

Namespace reference type.

Example

ns Namespace("::hot::str")
// Reference to the ::hot::str namespace

Null core

fn (): Null

Null type. Represents absence of a value.

Example

Null()      // null
is-null(n)  // check for null

OnErr core

Disposition for how eligible higher-order functions (map, pmap, map-indexed, mapcat, call) handle a normal domain Result.Err.

  • OnErr.Force (default) — force the Err, stopping the operation and propagating the error to the caller (fail-fast).
  • OnErr.Preserve — keep the Err as a value according to the function's return shape. For map-shaped functions, the Err is retained as an output element. For call, the callee's Err is returned as the call result.

OnErr only applies to normal err(...) / Result.Err values. fail(), cancel(), and hard runtime errors remain exceptional and halt unless they are wrapped in an explicit containment boundary.

Passed as an optional trailing argument:

map(items, risky)                    // Force (default): fail-fast on Err
map(items, risky, OnErr.Preserve)    // preserve Err slots in the result
call(risky, [arg], OnErr.Preserve)   // return a callee Err as a value

Result core

A enum (variant union) type representing either success (Ok) or failure (Err).

Example

success Result.Ok(42)
failure Result.Err("Something went wrong")

success  // 42
failure  // "Something went wrong"

is-ok(success)   // true
is-err(failure)  // true

// Or use the convenience functions:
success ok(42)
failure err("Something went wrong")

Str core

fn (value: Any): Str

String type. Convert any value to a string.

Example

Str(42)         // "42"
Str(true)       // "true"
Str([1, 2, 3])  // "[1, 2, 3]"

Var core

fn (value: Str | Var): Var

Variable reference type.

Example

v Var("my-var")
// Reference to a variable by name

Vec core

fn (value: Any, rest: Any): Vec

Vector (array) type. With one argument, coerces it to a vector: strings split into characters, maps become [key, value] pairs, bytes become ints, and vectors pass through. With multiple arguments, collects them into a vector.

Example

Vec(1, 2, 3)       // [1, 2, 3]
Vec("abc")         // ["a", "b", "c"]
Vec({a: 1, b: 2})  // [["a", 1], ["b", 2]]
Vec(Bytes([7, 8])) // [7, 8]
Vec(42)            // [42]