Language Guide

Variables

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

Functions

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
})

Control Flow

if / else if / else

score = 85
if score >= 90 {
  print("A")
} else if score >= 80 {
  print("B")
} else {
  print("C")
}

while

n = 10
total = 0
while n > 0 {
  total = total + n
  n = n - 1
}

for — unified iteration

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]))
}

Compound Assignment

x = 10
x += 5   // 15
x -= 3   // 12
x *= 2   // 24
x /= 4   // 6
x %= 3   // 0

Collections

Lists

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

Objects

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

String Methods

print("hello".upper())          // HELLO
print("a,b,c".split(","))    // ["a", "b", "c"]
print("hello".contains("ell")) // true
print("42".to_number())         // 42

Number Methods

print((3.14).floor())  // 3
print((-5).abs())     // 5
print(9.sqrt())       // 3
print(2.pow(3))        // 8

Async / Await

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]

Failure Handling

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
}

Modules

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"
}

List Methods

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]