Kharat Bot Docs

KAL expressions & built-ins

Types, literals, the full operator set with precedence, comparison semantics and every built-in function.

Types#

KAL values are STRING, NUMBER, BOOLEAN, NULL, ARRAY or MAP (TYPE(v) returns exactly these spellings). Missing data reads as null β€” an out-of-range array index, an absent map key or an unset context field all yield null rather than an error.

Literals#

kal (fragment)
DECLARE count = 42;              // NUMBER (integers and decimals)
DECLARE label = "hello";         // STRING  - escapes: \n \r \t \" \' \\ \uXXXX
DECLARE flag = true;             // BOOLEAN
DECLARE nothing = null;          // NULL
DECLARE tags = ["news", "fun"];  // ARRAY
DECLARE scores = {"alice": 3};   // MAP

Escapes in strings: \n, \r, \t, \", \', \\ and \uXXXX. Literal line breaks inside a string are rejected.

Operators#

CategoryOperatorsNotes
Arithmetic+ - * / %/ by zero is a runtime error; % by zero too
Concatenation+If either side is a string, + joins as strings
Comparison< <= > >=Numbers only
Equality== !=Deep equality β€” maps and arrays compare by content
IdentityISStrict β€” two separately-built maps are never IS each other
MembershipIN / CONTAINSArrays (value), strings (substring), maps (key)
Prefix/suffixSTARTS_WITH / ENDS_WITHStrings only
LogicAND OR NOT (also && `
Assignment= += -= *= /= %=With SET

Precedence, lowest to highest: OR β†’ AND β†’ comparisons & IN/CONTAINS β†’ < <= > >= β†’ + - β†’ * / %. Parentheses override everything.

Member access, indexing, iteration sources#

kal (fragment)
user_info.name              // MAP property
user_info.stats.messages    // nested maps
scores["alice"]             // MAP by key
tags[0]                     // ARRAY by index (out of range -> null)
LENGTH(tags)                // ARRAY or MAP or STRING size

Built-in functions#

FunctionSignatureReturns
LENGTH(v)string / array / mapNUMBER
LOWER(s) UPPER(s) TRIM(s)stringSTRING
SUBSTRING(s, start[, len])string, numbersSTRING
REPLACE(s, search, repl)stringsSTRING
SPLIT(s, delim)stringsARRAY
JOIN(arr, delim)array, stringSTRING
MIN(a, b) MAX(a, b)numbersNUMBER
ROUND(n[, decimals])numberNUMBER
FLOOR(n) CEIL(n) ABS(n)numberNUMBER
RANDOM([min, max])numbers (inclusive)NUMBER
NOW()β€”NUMBER (epoch ms)
DATE(v) TIME(v)epoch number or stringSTRING
DURATION(ms)numberSTRING (human-readable)
SECONDS_AGO(n) MINUTES_AGO(n) HOURS_AGO(n) DAYS_AGO(n)epochNUMBER
TYPE(v)anySTRING
EXISTS(v) NOT_EXISTS(v)anyBOOLEAN
EMPTY(v) NOT_EMPTY(v)string / array / mapBOOLEAN
LAST_ACTION()β€”MAP (previous action's result)
UI_BUTTON UI_SELECT_MENU UI_OPTION UI_ACTION_ROW UI_CLONE_WITHcomponent buildersMAP β€” see Components

A worked example#

kal
KAL VERSION 2.0;
AUTOMATION text_tools {

    WHEN COMMAND analyze (word AS STRING) {
        DECLARE ts = NOW();
        DECLARE stamp = DATE(ts);
        DECLARE clean = TRIM(LOWER(word));
        DECLARE parts = SPLIT(clean, " ");
        DECLARE joined = JOIN(parts, "-");
        DECLARE verdict = "unknown";

        IF clean STARTS_WITH "kh" THEN {
            SET verdict = "kharat-prefixed";
        } END IF;

        REPLY "[" + stamp + "] " + joined + " (" + ("" + LENGTH(parts)) + " parts, " + verdict + ")";
    }
}

Truthiness#

IF, WHILE, AND/OR treat exactly these as false: null, false, 0, "" and NaN. Everything else β€” including empty arrays and empty maps β€” is true.