Quick reference for the Tea language: syntax, built-ins, and core constructs. Tea is meant for small scripts and automation, not as a full “full-stack” language.
;.{ … }.\n, \t, \", \\.import "path/to/file.t"; — exported symbols come from files that use export.import "@vendor/module.t"; resolves to ./teahouse/vendor/module.t (from the current working directory).@... imports have lower priority and do not overwrite existing symbols.
Control flow: if, else, for, while, return, fn,
break, continue, import, export, throw.
Booleans: true, false.
Start with a letter or underscore, then letters, digits, or underscores:
[A-Za-z_][A-Za-z0-9_]*. Names are case-sensitive.
42, -13.14, -0.5"hello"true, false[1, 2, "a"] — elements may mix types.{"key": value} — keys are strings; values may be any Tea expression (including nested dicts/arrays).// to end of line#! …/* … */
Explicit types (lowercase, as in the lexer): int, float, str,
bool, void, array, dict.
int n = 10;
str s = "text";
bool ok = true;
array xs = [1, 2, 3];
dict d = {name: "tea", year: 2026};
Declare with a type and optional initializer; functions use fn, return type before the name, or
void when there is no return value. Variadic functions use ...name.
int x;
x = 1;
int fn add(int a, int b) {
return a + b;
};
void fn greet(str name) {
print("Hello, " + name);
};
void fn log(...parts) {
print(parts);
};
+ - * / %== != < <= > >=and (also && / &), or (also || / |)if (condition) {
// ...
} else {
// ...
};
for (int i = 0; i < len(xs); i = i + 1) {
if (i == 10) {
break;
};
print(xs[i]);
};
while (n > 0) {
n = n - 1;
};
Arrays and strings use integer indexes; dictionaries use keys. Indexing can be nested.
array xs = ["tea", "cup"];
dict page = {title: "Home", tags: xs};
print(xs[0]); // tea
print(page["tags"][1]); // cup
print("tea"[0]); // t
The runtime provides, among others:
print(…) — write to stdoutstdout("text") — write without a trailing newline (e.g. prompts)input — read one line from stdin (typical: str name = input;)cmd("shell command") — run a shell command, output as a stringread("path") / write("path", content) — read/write fileslen(x) — length (string, array, or dict)split(str, delimiter), find(str, pattern) — string helpersdictKeys(dict) — returns an array of keys (as strings)dictValues(dict) — returns an array of valuesjson(str) — parse JSON strings; objects become dicts, arrays become arrays, and null becomes an empty dictsleep(seconds), quit(), assert(actual, expected[, "message"])cast(…) — type conversionSYSARGS, LRC — command-line args and last return code (see interpreter docs)
http sends plain http:// requests and returns a dictionary with
status, body, headers, and error.
Convenience wrappers are available as request, get, post,
put, patch, and delete.
dict response = get("http://127.0.0.1:8080/hello");
assert(response["status"], 200);
dict created = post("http://127.0.0.1:8080/items", "{\"ok\":true}");
dict payload = json(created["body"]);
dict custom = http({
method: "PUT",
url: "http://127.0.0.1:8080/items/1",
headers: {"Content-Type": "application/json"},
body: "{\"name\":\"tea\"}"
});
serve starts a simple HTTP server. The handler receives a request dict
(method, path, query, body, headers)
and returns a response dict (status, headers, body).
dict fn app(dict req) {
return {
status: 200,
headers: {"Content-Type": "text/plain"},
body: "hello from tea"
};
};
serve({port: 8080, handler: app});
More helpers can be pulled in via import from libraries (for example common/string.t with
replace, replaceMany, and so on).