Functions
Declaration
cleat
fn add(a: int, b: int) -> int { return a + b }
Functions without a return type return void:
cleat
fn greet(name: string) needs { io } { io.println("hello, ${name}") }
Default parameters
cleat
fn greet(name: string, greeting: string = "Hello") -> string { return "${greeting}, ${name}!" } greet("Alice") // "Hello, Alice!" greet("Alice", "Hi") // "Hi, Alice!"
Defaults must be constant expressions. Parameters with defaults must come after required parameters.
Named arguments
cleat
fn create_user(name: string, role: string = "user", active: bool = true) -> User { return User { name: name, role: role, active: active } } create_user(name: "Alice", role: "admin")
Named arguments can appear in any order and are resolved at compile time.
Effect declarations
Functions that perform side effects must declare them with needs:
cleat
fn fetch(url: string) -> Result[string, string] needs { net } { let resp: http.Response = http.get(url)? return Ok(resp.body) }
A function without needs is pure — it cannot call effectful functions. See Effect System.
Methods
Methods are declared with a receiver parameter:
cleat
type Point = struct { x: int, y: int } fn (p: Point) distance() -> float { return math.sqrt(math.pow(p.x, 2.0) + math.pow(p.y, 2.0)) } let d = Point { x: 3, y: 4 }.distance() // 5.0
Lambdas
Anonymous functions for use with map, filter, and pipes:
cleat
let double = fn(x: int) -> int { return x * 2 } let result = [1, 2, 3] |> map(fn(x: int) -> int { return x * 2 })
Native functions
Stdlib packages use @native to bind Cleat declarations to Go implementations:
cleat
fn">@native("JsonEncode") fn encode(value: any) -> string
The body is in Go (runtime/cleat/json.go). Users don't write @native functions — they're for stdlib authors only.