Variables are declared by assignment — no let, var, or const needed. They're mutable by default and dynamically typed.
// declaration + assignment x = 10 name = "ysc" flag = true // reassignment x = x + 5
Declared with fun. Use ret to return a value from a block body. Single-expression closures (|x| x * 2) have an implicit return.
fun add(a, b) { ret a + b } // single-expression closure (implicit return) doubled = [1, 2, 3].map(|x| x * 2) // block-body closure (needs explicit ret) evens = [1, 2, 3].filter(|x| { ret x % 2 == 0 })
score = 85 if score >= 90 { print("A") } else if score >= 80 { print("B") } else { print("C") }
n = 10 total = 0 while n > 0 { total = total + n n = n - 1 }
The same for construct works on ranges, lists, and objects through a single ForNext instruction.
// Range for i in 0..5 { print(i) } // List items = [10, 20, 30] for x in items { print(x) } // Object (iterates keys) obj = {name: "Alice", age: 30} for k in obj { print(k + ": " + str(obj[k])) }
x = 10 x += 5 // 15 x -= 3 // 12 x *= 2 // 24 x /= 4 // 6 x %= 3 // 0
fibo = [0, 1, 1, 2, 3, 5] print(fibo[0]) // 0 print(len(fibo)) // 6 // Rust-style repeat initialization scores = [0; 5] scores[0] = 95
person = {name: "Alice", age: 30}
print(person.name) // Alice (dot access)
print(person["name"]) // Alice (bracket access)
// Object methods
print(person.keys()) // ["name", "age"]
print(person.has("age")) // true
print("hello".upper()) // HELLO print("a,b,c".split(",")) // ["a", "b", "c"] print("hello".contains("ell")) // true print("42".to_number()) // 42
print((3.14).floor()) // 3 print((-5).abs()) // 5 print(9.sqrt()) // 3 print(2.pow(3)) // 8
Async functions return Promises. Use await to resolve. Awaiting an array resolves all promises in parallel via a compound promise tracked by the event loop.
async fun fetch_url(url) { ret await fetch(url) } // Sequential a = await fetch_url("https://example.com") b = await fetch_url("https://example.com") // Parallel p1 = fetch_url("https://example.com") p2 = fetch_url("https://example.com") results = await [p1, p2]
Failures are tagged NaN values that propagate through expressions. Use or for fallbacks and except for pattern matching — no try/catch, no stack unwinding.
// Fallback with 'or' x = some_failing_expression or 0 // Pattern matching with 'except' x = divide(a, b) except { |DivisionByZero -> 0 |_ -> -1 }
Import other source files with use and a dot-separated path. Items marked exp are visible to importers.
use models.user exp fun public_api() { ret "visible to importers" }
numbers = [1, 2, 3, 4, 5] squares = numbers.map(|x| x * x) // [1, 4, 9, 16, 25] evens = numbers.filter(|x| x % 2 == 0) // [2, 4] sum = numbers.reduce(0, |a, v| a + v) // 15 reversed = numbers.reversed() // [5, 4, 3, 2, 1]