Functions are defined using the keyword fn and must have explicit type annotations.

fn double(x: Int) -> Int {
  x * 2

Functions can be called using C-style function calls:


Void Functions

Functions that do not return a value can omit the return type instead of explicitly saying Void.

fn ignore<T>(x: T) {
  // evaluates whatever is passed into `x`, but ignores it's result


All the functions are automatically curried, which means that both of the following are equivalent.

fn add(x: Int, y: Int) -> Int {
  x + y

fn add(x: Int) -> (Int) -> Int {
  fn add'(y: Int) -> Int {
    x + y

Both of the add functions defined above can be called in any of the following ways.

add(3, 5)


let add3 = add(3)

Universal Function Call Syntax (UFCS)

UFCS allows you to call a function as if was a method of its first argument. Let’s see an example:

fn bool_to_int(x: Bool) -> Int {
  if x { 1 } else { 0 }

bool_to_int(False) //=> 0 : Int

// Alternatively

True.bool_to_int() //=> 1 : Int

This makes it possible to “extend” a class after its definition.

class C { /* ... */ }

let c = C({})

fn printC(self: C) {
  // ...


And behaves similar to the reverse application operator in other functional languages like Elm, F# and OCaml (and recently proposed to JavaScript):

is equivalent to the following in Elm for example:

list |> map f |> filter g |> sort h |> iter i

with the difference that with UFCS the object is passed as the first argument and with the reverse application operator it would be passed as the last argument.