# Functions

Functions and higher-order functions are the key building block of a functional programming language.

In Flix, top-level functions are defined with the
`def`

keyword.
For example:

```
def add(x: Int32, y: Int32): Int32 = x + y + 1
```

A definition consists of the function name followed by an argument list, the return type, and the function body. Although Flix supports type inference, top-level function definitions must declare the type of their arguments and their return type.

In Flix, all function arguments and local variables must be used. If a function argument is not used it must be prefixed with an underscore to explicitly mark it as unused.

## First-Class and Higher-Order Functions

A *higher-order function* is a function that takes a
parameter which is itself a function.
For example:

```
def twice(f: Int32 -> Int32, x: Int32): Int32 = f(f(x))
```

Here the `twice`

function takes two arguments, a
function `f`

and an integer `x`

, and applies `f`

to
`x`

two times.

We can pass a lambda expression to the `twice`

function:

```
twice(x -> x + 1, 42)
```

which evaluates to `44`

since `42`

is incremented
twice.

We can also define a higher-order function that requires a function which takes two arguments:

```
def twice(f: (Int32, Int32) -> Int32, x: Int32): Int32 =
f(f(x, x), f(x, x))
```

which can be called as follows:

```
twice((x, y) -> x + y, 42)
```

We can call a higher-order function with a top-level function as follows:

```
def inc(x: Int32): Int32 = x + 1
def twice(f: Int32 -> Int32, x: Int32): Int32 = f(f(x))
twice(inc, 42)
```

## Function Type Syntax

Depending on the number of arguments to a function, the syntax for the function type differs:

```
Unit -> Int32 // For nullary functions
Int32 -> Int32 // For unary functions
(Int32, Int32, ...) -> Int32 // For the rest
```

## Function Composition

Flix supports several operators for function composition and pipelining:

```
let f = x -> x + 1;
let g = x -> x * 2;
let h = f >> g; // equivalent to x -> g(f(x))
```

Here `>>`

is forward function composition.

We can also write function applications using the pipeline operator:

```
List.range(1, 100) |>
List.filter(x -> x `Int32.mod` 2 == 0) |>
List.map(x -> x * x) |>
println;
```

Here `x |> f`

is equivalent to the function
application `f(x)`

.

## Curried by Default

Functions are curried by default. A curried function can be called with fewer arguments than it declares returning a new function that takes the remainder of the arguments. For example:

```
def sum(x: Int32, y: Int32): Int32 = x + y
def main(): Unit \ IO =
let inc = sum(1);
inc(42) |> println
```

Here the `sum`

function takes two arguments, `x`

and
`y`

, but it is only called with one argument inside
`main`

.
This call returns a new function which is
similar to `sum`

, except that in this function `x`

is always bound to `1`

.
Hence when `inc`

is called with `42`

it returns `43`

.

Currying is useful in many programming patterns.
For example, consider the `List.map`

function.
This function takes two arguments, a function of
type `a -> b`

and a list of type `List[a]`

, and
returns a `List[b]`

obtained by applying the
function to every element of the list.
Now, if we combine currying with the pipeline
operator `|>`

we are able to write:

```
def main(): Unit \ IO =
List.range(1, 100) |>
List.map(x -> x + 1) |>
println
```

Here the call to `List.map`

passes the function
`x -> x + 1`

which *returns* a new function that
expects a list argument.
This list argument is then supplied by the pipeline
operator `|>`

which, in this case, expects a list
and a function that takes a list.

## Pipelines

Flix supports the pipeline operator `|>`

which is
simply a prefix version of function application (i.e.
the argument appears before the function).

The pipeline operator can often be used to make functional code more readable. For example:

```
let l = 1 :: 2 :: 3 :: Nil;
l |>
List.map(x -> x * 2) |>
List.filter(x -> x < 4) |>
List.count(x -> x > 1)
```

Here is another example:

```
"Hello World" |> String.toUpperCase |> println
```

## Operators

Flix has a number of built-in unary and infix operators. In addition Flix supports infix function application by enclosing the function name in backticks. For example:

```
123 `sum` 456
```

is equivalent to the normal function call:

```
sum(123, 456)
```

In addition, a function named with an operator name (some combination of `+`

, `-`

, `*`

, `<`

, `>`

, `=`

, `!`

, `&`

, `|`

, `^`

, and `$`

) can also be used infix. For example:

```
def <*>(x: Int32, y: Int32): Int32 = ???
```

can be used as follows:

```
1 <*> 2
```