Lambda_Cheatsheet.md
July 7, 2026 · View on GitHub
CLI Commands
lambda # Start REPL
// REPL Commands: quit, help, clear
lambda script.ls # Eval functional script
lambda run script.ls # Run procedual script
lambda --help # Show help
Validation:
lambda validate file.json -s schema.ls # With schema
lambda validate file.json # Default schema
Type System
Scalar Types:
null bool int float decimal
string symbol binary datetime path
i8 i16 i32 i64 // Sized signed integers
u8 u16 u32 u64 // Sized unsigned integers
f16 f32 f64 // Sized floats
Container Types:
range, 1 to 10 // Range (inclusive both ends)
array, [123, true] // Array of values
map, {key: 'symbol'} // Map
element, <div class: bold; "text" <br>> // Element
Type Operators:
int | string // Union type
int & number // Intersection
int? // Optional (int | null)
int* // Zero or more
int+ // One or more
int[] // Array of ints (same as int*)
int[5] // Array of exactly 5 ints
[int*] // Bracket form: array of 0+ ints
[int+] // Bracket form: array of 1+ ints
fn (a: int, b: string) bool // Function type
fn int // Same as fn () int
{a: int, b: bool} // Map type
<div id:symbol; <br>> // Element type
Type Declarations:
type User = {name: string, age: int}; // Map type alias
type Point = (float, float); // Tuple type
type Result = int | error; // Union type
Object Types
Definition:
type Point { x: float, y: float } // Fields only
type Counter {
value: int = 0; // Default value
fn double() => value * 2 // Functional
fn add(n: int) => value + n
pn inc() { value = value + 1 } // Procedural
}
type Circle : Shape { radius: float; } // Inheritance
Literals & Access:
let p = <Point x: 1.0, y: 2.0> // Object literal
let c = <Counter> // All defaults
p.x // Field access
c.double() // Method call
<Point *:p, x: 5.0> // Copy and override
Type Checking (nominal only):
p is Point // true
p is object // true
p is map // true (objects are map-compatible)
{x: 1} is Point // false (plain maps don't match)
Constraints:
type User {
name: string that (len(~) > 1), // Field constraint
age: int that (0 <= ~ <= 150);
that (~.name != "admin") // Object constraint
}
Self reference ~:
type Vec {
x: float, y: float;
fn len() => math.sqrt(x**2 + y**2)
fn scale(f) => <Vec ~, x:~.x*f, y:~.y*f> // ~ = self
}
Literals
Numbers:
42 // Integer
3.14 // Float
1.5e-10 // Scientific notation
123.45n // Decimal128 (~34 digits)
123.45N // Decimal (ultra precision, 200 digits)
inf nan // Special values
0xFF // hexdecimal literal for int value
// Sized numeric literals (postfix suffix)
42i8 -128i8 1000i16 100000i32 100i64
255u8 60000u16 3000000000u32 1000u64
0.5f16 3.14f32 2.7f64
Strings & Symbols:
"hello" // String
"multi-line // Multi-line string
string"
'symbol' // Symbol
symbol // Unquoted symbol
'name' == "name" // false: symbol != string
"" == null // false: empty string is a string value
not "" // true: empty string is falsy
// '' is invalid: empty symbols do not exist
Binary:
b'\xDEADBEEF' // Hex binary
b'\64QUVGRw==' // Base64 binary
DateTime:
t'2025-01-01T14:30:00Z' // DateTime
t'2025-04-26' is date // Sub-types: date
t'10:30:00' is time // Sub-types: time
// Member properties
dt.date dt.year dt.month dt.day
dt.time dt.hour dt.minute dt.second dt.millisecond
dt.weekday dt.yearday dt.week dt.quarter
dt.unix dt.timezone dt.utc_offset dt.utc dt.local
// Formatting
dt.format("YYYY-MM-DD") dt.format('iso')
// Constructors
datetime() today() justnow() // current date/time
datetime(2025, 4, 26, 10, 30)
date(2025, 4, 26) time(10, 30, 45)
Collections:
[1, 2, 3] // Array
{a: 1, b: 2} // Map
<div id: "main"> // Element
Indexing & Slicing:
arr[0] // First element
arr.0 // Alt. syntax for const index
arr[1 to 3] // Slice (indices 1, 2, 3)
map.key // Map field access
map["key"] // Map field by string
"hello"[1 to 3] // "ell" — string slicing
'hello'[1 to 3] // 'ell' — symbol slicing
"café"[2 to 3] // "fé" — UTF-8 aware
Namespaces (via import with bare URI):
import svg: 'http://www.w3.org/2000/svg'
import xlink: 'http://www.w3.org/1999/xlink'
<svg.rect svg.width: 100> // Namespaced tag & attr
// desugars to: <svg.rect svg: {width: 100}>
elem.svg.width // Chained sub-map access
elem.svg // {width: 100} sub-map
svg.rect // Qualified symbol
symbol("href", 'xlink_url') // Namespaced symbol
Variables & Declarations
Let Expressions (immutable):
(let x = 5, x + 1, x * 2) // Single binding
(let a = 1, b = 2, a + b) // Multiple bindings
Let Statements (immutable):
let x = 42; // Immutable binding
let y : int = 100; // With type annotation
let a: i8 = 42i8; // Sized type annotation
let b: f32 = 3.14f32; // Sized float annotation
let a = 1, b = 2; // Multiple bindings
x = 10 // ERROR E211: cannot reassign let binding
Var Statements (mutable, pn only):
var x = 0; // Mutable variable
var y: int = 42; // With type annotation
var a: int[] = [1, 2, 3]; // Array of ints
var b: float[] = [0.1, 0.2]; // Array of floats
x = x + 1 // OK: reassignment
x = "hello" // OK: type widening (int → string)
y = "oops" // ERROR E201: annotated type enforced
Operators
Arithmetic: addition, subtraction, multiplication, division, integer division, modulo, exponentiation
+ - * / div % **
Spread: *
let a = [1, 2, 3]
(*a, *[10, 20]) // (1, 2, 3, 10, 20)
Comparison: equal, not equal, less than, less equal, greater than, greater equal
== != < <= > >=
== performs structural deep equality on all types:
[1, 2] == [1, 2] // true (array)
{a:1, b:2} == {b:2, a:1} // true (map, order-independent)
[1] == [1.0] // true (numeric promotion)
(1 to 3) == [1, 2, 3] // true (cross-type sequence)
Logical: logical and, or, not
and or not
Type & Set: type check, membership, range, union, intersection, exclusion
is in to | & !
Query: type-based search
? .? // recursive descendant search
expr[T] // child-level query (direct only)
Vector Arithmetic: scalar broadcast, element-wise ops
1+[2,3] = [3,4] [1,2]*2 = [2,4] [1,2]+[3,4] = [4,6]
Use ++ for list/array concat: [1,2] ++ [3,4] = [1,2,3,4].
Pipe Expressions
Pipe |> with current item ~:
[1,2,3] |> ~ * 2 // [2,4,6] - map over items
[1,2,3] |> sum // 6 - aggregate (no ~)
users |> ~.age // [12,20,62] - extract field
['a','b'] |> {i:~#, v:~} // ~# = index/key
Filter with that:
[1,2,3,4,5] that (~ > 3) // [4,5]
users that (age >= 18) |> ~.name // filter then map
[1,2,3] |> ~ ** 2 that (~ > 5) |> sum // 13 (4+9)
Spreading in Array Literals: pipe and filter results flatten
[1, [2,3] |> ~, 4, 5] // [1, 2, 3, 4, 5]
[0, [1,2,3] |> ~ * 10, 99] // [0, 10, 20, 30, 99]
[1, [3,5,7] that (~ > 4), 9] // [1, 5, 7, 9]
Query Expressions
Results in document order (depth-first, pre-order).
Query ? — attributes + all descendants:
html?<img> // all <img> at any depth
html?<div class: string> // <div> with class attr
data?int // all int values in tree
data?(int | string) // all int or string values
data?{name: string} // maps with string 'name'
data?{status: "ok"} // maps where status == "ok"
Self-inclusive query .? — self + attributes + all descendants:
div.?<div> // includes div itself if it matches
el.?int // self + all int values in subtree
42.?int // [42] — trivial self-match
Child-level query [T] — direct attributes + children only (no recursion):
[1, "a", 3, true][int] // [1, 3] — int items
{name: "Alice", age: 30}[string] // ["Alice"]
el[element] // direct child elements only
el[string] // attr values + text children
File Output (procedural only)
// Target can be string, symbol, or path
output(data, 'output.txt') // file under CWD
output(data, "./temp/output.txt") // output at a relative path
output(data, "output.txt", {mode: "append"})
output(data |> format('json'), "output.json")
Data type determines output format:
- String: raw text (no formatting)
- Binary: raw binary data
- Other types: Lambda/Mark format
Control Flow
If Expressions (parenthesized condition, else required):
if (x > 0) "positive" else "non-positive"
if (score >= 90) "A"
else if (score >= 80) "B" else "C"
if (x > 0) "pos" else { "neg" } // block else
If Statements (block body, else optional):
if x > 0 { "positive" }
if condition { something() } else { otherThing() }
if x > 0 { compute() } else "default" // expr else
Both forms share the same else syntax: else expr, else { stam }, or else if ....
Match Expressions:
// Type patterns or Literal
match value {
case 200: "OK" // case literal
case string: "text" // case type
case int | float: "number" // case type union
case Circle: // case object type
3.14 * ~.r ** 2
default: "other"
}
// String pattern arms (full-match semantics)
string digits = \d+
string alpha = \a+
match input {
case digits: "number" // case named pattern
case alpha: "word"
default: "other"
}
For Expressions: (produce spreadable arrays — pipe/filter also spread, see above)
for (x in [1, 2, 3]) x * 2 // [2, 4, 6]
for (i in 1 to 5) i * i // [1, 4, 9, 16, 25]
for (x in data) if (x > 0) x else 0 // Conditional
// Nested for-expressions flatten
[for (i in 1 to 2) for (j in 1 to 2) i*j] // [1,2,2,4]
// Empty for produces spreadable null (skipped)
[for (x in [] ) x] // []
// for loop over map by keys
for (k at {a: 1, b: 2}) k // 'a', 'b'
for (k, v at {a: 1, b: 2}) k ++ v // ['a1', 'b2']
For Expression Clauses: let, where, order by, limit, offset
for (x in data where x > 0) x // filter
for (x in data, let sq = x*x) sq // let binding
for (x in [3,1,2] order by x) x // (1,2,3)
for (x in [3,1,2] order by x desc) x // (3,2,1)
for (x in data limit 5 offset 10) x // pagination
for (x in data, let y=x*2
where y>5 order by y desc limit 3) y
For Statements:
for item in collection { transform(item) }
Procedural Control (in pn):
var x=0; // Mutable variable
while(c) { break; continue; return x; }
Assignment Targets (in pn):
x = 10 // Variable reassignment (var only)
arr[i] = val // Array element reassignment
obj.field = val // Map field reassignment
elem.attr = val // Element attribute reassignment
elem[i] = val // Element child reassignment
Functions
Function Declaration:
// Function with statement body
fn add(a: int, b: int) int { a + b }
// Function with expression body
fn multiply(x: int, y: int) => x * y
// Anonymous function
let square = (x) => x * x;
// Procedural function
pn f(n) { var x=0; while(x<n) {x=x+1}; x }
// Array parameters
pn advance(pos: float[], vel: float[], n: int) { ... }
Advanced Features:
fn f(x?:int) // optional param
fn f(x=10) // default param value
fn f(...) // variadic args
f(b:2, a:1) // named param call
fn outer(n) { fn inner(x)=>x+n; inner } // closure
String Patterns
Define named patterns for string validation and matching. Uses regex-like syntax integrated into the type system.
Definition:
string digits = \d+ // one or more digits
string email = \w+ "@" \w+ "." \a[2,6] // email-like
string ws = \s+ // whitespace
symbol keyword = 'if' | 'else' | 'for' // symbol pattern
Type check (is) — full-match semantics:
"hello@world.com" is email // true
"abc" is email // false
"123" is digits // true
Character classes: \d digit, \w word, \s whitespace, \a alpha, \. any char, ... any string
Quantifiers: ? optional, + one or more, * zero or more, [n] exactly n, [n,m] range
System Functions
Type:
int(v) int64(v) float(v) decimal(v) string(v) symbol(v) binary(v) number(v) type(v) len(v)
type() returns the specific type name for sized numerics: type(42i8) → "i8", type(3.14f32) → "f32"
Math:
math.pi math.e abs(x) sign(x) min(a,b) max(a,b) round(x) floor(x) ceil(x) math.trunc(x) math.sqrt(x) math.cbrt(x) math.hypot(x,y) math.pow(b,e) math.log(x) math.log2(x) math.log10(x) math.log1p(x) math.exp(x) math.exp2(x) math.expm1(x) math.sin(x) math.cos(x) math.tan(x) math.asin(x) math.acos(x) math.atan(x) math.atan2(y,x) math.sinh(x) math.cosh(x) math.tanh(x) math.asinh(x) math.acosh(x) math.atanh(x) math.random(seed) → [value, new_seed]
Stats:
sum(v) avg(v) math.mean(v) math.median(v) math.variance(v) math.deviation(v) math.quantile(v,p) math.prod(v)
Date/Time:
datetime() today() now() justnow() date(dt) time(dt)
Range:
s to e creates a range from s to e (inclusive both ends). range(s,e,step) creates a range with custom step (exclusive end).
1 to 5 // [1, 2, 3, 4, 5]
range(0, 10, 2) // [0, 2, 4, 6, 8]
String:
replace(str,old,new) split(str,sep) join(strs,sep) find(str,pattern) normalize(str) ord(str) chr(int)
All three accept both plain strings and named patterns as the second argument:
string digit = \d
string digits = \d+
string ws = \s+
// replace(str, pattern_or_string, replacement)
replace("a1b2c3", digit, "X") // "aXbXcX"
replace("hello world", ws, " ") // "hello world"
replace("abc", "b", "") // "ac"
// split(str, pattern_or_string)
split("a1b2c3", digit) // ["a", "b", "c", ""]
split("hello world", ws) // ["hello", "world"]
split("a,b,c", ",") // ["a", "b", "c"]
split("a1b2c3", digit, true)
// ["a", "1", "b", "2", "c", "3", ""] — keep delimiters
// find(str, pattern_or_string) → [{value, index}, ...]
find("a1b22c333", digits)
// [{value:"1", index:1}, {value:"22", index:3}, ...]
find("hello world", "lo") // [{value: "lo", index: 3}]
Collection:
slice(v,i) slice(v,i,j) set(v) all(v) any(v) reverse(v) sort(v) unique(v) take(v,n) drop(v,n) zip(a,b) fill(n,x) range(s,e,step) map(f,v) filter(f,v) reduce(f,v,init)
Vector:
math.dot(a,b) math.norm(v) math.cumsum(v) math.cumprod(v) argmin(v) argmax(v) diff(v)
I/O:
input(file,fmt) format(data,fmt) print(v) output(data,file) fetch(url,opts) cmd(c,args) error(msg) varg()
Input/Output Formats
Supported Input Types: json, xml, yaml, markdown, csv, html, latex, toml, rtf, css, ini, math, pdf
input("path/file.md", 'markdown') // Input Markdown
Input with Flavors: e.g. math flavors: latex, typst, ascii
input("math.txt", {'type':'math', 'flavor':'ascii'})
Output Formatting: json, yaml, xml, html, markdown
format(data, 'yaml') // Format as YAML
Modules, Imports & Exports
Import Syntax:
import module_name // Built-in module
import .relative_module // Relative to script's dir
import .path.to.module // Nested relative import
import alias: .module // Import with alias
Export Declarations:
pub PI = 3.14159 // Export variable
pub fn square(x) => x * x // Export function
pub pn log(msg) { print(msg) } // Export procedure
pub type Score = int // Export type alias
pub type Counter { // Export object type
value: int = 0;
fn double() => value * 2
}
pub data^err = input(\"f\") // Exp. data and err
Module Usage:
// In math_utils.ls:
pub PI = 3.14159
pub type Vec2 { x: float, y: float; fn len() =>
math.sqrt(x**2 + y**2) }
// In main.ls:
import .math_utils
let area = PI * r ** 2
let v = <Vec2 x: 3.0, y: 4.0>
v.len() // 5.0
v is Vec2 // true
Error Handling
Creating Errors:
error("Message") error("load failed", inner_err)
error({code: 304, message: "div by zero"})
Error Return Types (T^E):
fn parse(s: string) int^ {...} // int or any error
fn divide(a, b) int ^ DivErr {...} // specific error
fn load(p) Config ^ ParseErr|IOErr {...} // multi errors
raise error , or propagate error with ^
fn compute(x: int) int^ {
if (b == 0) raise error("div by zero") // raise error
let a = parse(input)^ // return immediately on error
let b = divide(a, x)^ // return immediately on error
a + b
}
fun()^ // propagate error, discard value
let a^err — destructure value and error:
let result^err = divide(10, x)
if (^err) print(err.message) // ^err to check error
else result * 2
Operator Precedence (High to Low)
()[].?.?- Primary, query-+not!- Unary (not: logical NOT,!: type negation)**- Exponentiation*/div%- Multiplicative+-- Additive<<=>>=- Relational==!=- Equalityand- Logical ANDor- Logical ORto- Rangeisin- Type operations (is nanfor NaN detection)|where- Pipe and Filter
Quick Examples
Data Processing:
let data = input("sales.json", 'json')
let total = sum(
(for (sale in data.sales) sale.amount))
let report = {total: total,
count: len(data.sales)}
format(report, 'json')
Function Definition:
fn factorial(n: int) int {
if (n <= 1) 1 else n * factorial(n - 1)
}
Element Creation:
let article = <article title:"My Article"
<h1 "Introduction">
<p "Content goes here.">
>
format(article, 'html')
Comprehensions - Complex data processing:
(let data = [1, 2, 3, 4, 5],
let filtered = (for (x in data)
if (x % 2 == 0) x else 0),
let doubled = (for (x in filtered) x * 2), doubled)