Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Functions

Basic Functions

Functions are declared with fn. The body follows a colon and is indented:

fn add(x: i64, y: i64) -> i64:
  x + y

No return type means the function returns unit:

fn greet(name: String):
  print(name)

Short functions can be written inline:

fn double(x: i64) -> i64: x * 2
fn apply(x: i64) -> i64: compute(x)

Generics

Type parameters go in angle brackets after the function name:

fn identity<T>(x: T) -> T:
  x

With trait bounds:

fn print_it<T: Display>(x: T):
  print(x)

With where clauses:

fn convert<T, U>(x: T) -> U where T: Into<U>:
  x.into()

Effects

Functions that perform side effects declare them with !(...) after the return type:

fn read_file(path: String) -> String !(IO):
  // ...

fn complex(x: i64) -> String !(IO + State):
  // ...

See Effects & Handlers for the full effect system.

Multi-Clause Functions

Functions can pattern-match on their arguments using multiple clauses. The body contains (patterns): body clauses, similar to match:

fn fib(n: i64) -> i64:
  (0): 0
  (1): 1
  (n): fib(n - 1) + fib(n - 2)

Each clause lists patterns for the arguments in parentheses.

Function Type Parameters

Functions can accept other functions as parameters using fn(Args) -> Ret type syntax:

fn apply(f: fn(i64) -> i64, x: i64) -> i64:
  f(x)

Visibility and Attributes

Functions are public by default. Use pvt for private:

pvt fn helper() -> i64:
  42

Attributes precede the function:

#[inline]
fn fast(x: i64) -> i64:
  x * 2

Everything Combined

#[some_attr]
pvt fn kitchen_sink<T, U: Default>(x: T, y: U) -> Result<T, U> !(IO + State) where T: Display + Clone:
  // ...

Lambdas

Anonymous functions use pipe syntax:

let f = |x| x + 1
let add = |x, y| x + y
let constant = || 42

Lambdas are commonly used with higher-order functions:

items.map(|x| x * 2)
items.filter(|x| x > 0)
items.fold(0, |acc, x| acc + x)

Calling Functions

Standard call syntax:

add(5, 3)
f(g(x))
f(x + y, y * 2)

Method calls on values:

x.len()
x.concat(y)
x.trim().len()      // chaining

Path-qualified calls:

Foo::new()
std::io::File::open("test.txt")