# Functions

> Functions in Langoost — declarations, optional type annotations, anonymous functions and closures, variadic parameters, the spread operator, recursion, and hoisting.

# Functions

## Declaration

Functions are declared with `fn`. Parameter and return-type annotations are
optional but recommended:

```goost
fn greet(name: string): string {
    return "Hello, " + name + "!"
}

fn add(a, b) {          // annotations omitted
    return a + b
}
```

A function with no return type returns `void`. `return` with no value, or
falling off the end, returns `void`.

## Anonymous functions & closures

Functions are first-class values. Write an anonymous function with `fn(...)` and
assign it, pass it, or return it. Closures capture variables from the enclosing
scope:

```goost
let double = fn(x) { return x * 2 }
println(double(21))      // 42

fn makeAdder(n: int) {
    return fn(x) { return x + n }    // captures n
}
let add10 = makeAdder(10)
println(add10(5))        // 15
```

This is the form you pass to array methods and to APIs like `thread.core.spawn`:

```goost
let evens = [1, 2, 3, 4].filter(fn(n) { return n % 2 == 0 })
```

## Variadic parameters & spread

A final parameter prefixed with `...` collects any extra arguments into an
array:

```goost
fn sum(...nums) {
    let total = 0
    for n in nums {
        total += n
    }
    return total
}

println(sum(1, 2, 3, 4))   // 10
```

The `...` spread operator also expands an array into positional arguments at a
call site:

```goost
let args = [1, 2, 3]
println(sum(...args))      // 10
```

## Hoisting & recursion

Top-level function declarations are hoisted, so a function can be called before
it appears in the file, which also makes mutual recursion straightforward:

```goost
println(fib(10))         // works — fib is defined below

fn fib(n: int): int {
    if n <= 1 {
        return n
    }
    return fib(n - 1) + fib(n - 2)
}
```

Functions can also be nested inside other functions.

## Notes

- There are **no default or named parameters** — pass every argument
  positionally (or use a variadic / an object).
- Functions return a single value; to return several, return an array or object.

Continue to **[value methods](/docs/methods)** for the methods available on
strings, arrays, and numbers.