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.

Edit this page on GitHub