# »Language: Functions

Functions allow you to create reusable code to perform computations.

Below is a trivial example function that doubles a number and shows the main rule using the function:

``````double = func(x) {
return x * 2
}

main = rule { double(12) is 24 }
``````

Functions may contain any expressions, conditionals, and loops. They must return a value at the end of their execution. If no reasonable return value exists, the function should return undefined.

## »Creating a Function

A function is created by assigning a variable to a `func`.

A function can have zero or more parameters. These parameters are specified within parentheses `()` separated by commas. If a function has no parameters, the parentheses must still be present.

A function must terminate with a `return` statement to return a value back to the caller. Only a single value can be returned. The type of a return can vary between return statements.

Example:

``````add1 = func(x) { return x + 1 }
``````

This example creates a function that adds 1 to the parameter `x`. It is assigned to the variable `add1`.

## »Calling a Function

Functions are called by accessing their name followed by parentheses with a list of comma-separated values for the parameters. If the function takes no parameters, an empty set of parentheses must still be used to denote a function call.

To call the function in the example above:

``````x = 1
``````

## »Scoping

The body of a `func` creates a new scope.

The parent scope is the scope in which the function is created. This allows for the creation of functions within functions that can access their outer scopes.

Example:

``````f = func() {
a = 42
print(a) // 42
return undefined
}

print(a) // undefined
``````
``````a = 18
f = func() {
a = 42
return undefined
}

print(a) // 18
``````

And below is an example of creating a function in a function which uses outer values:

``````f = func() {
a = 42
double = func() { return a * 2 }
return double()
}

print(f()) // 84
``````

A more complex example below shows how scoping works when passing functions around as arguments or results:

``````f = func() {
a = 42
double = func() { return a * 2 }
return double
}

double = f()
print(double()) // 84
``````

## »Pass By Value

The parameters to a function are passed by value, but not deep copied. This means that elements of collections can still be modified but the root value cannot be changed.

Example:

``````f = func(x) {
x = "value"
return x
}

x = "outside"
f(x)
print(x) // "outside"
``````
``````f = func(x) {
append(x, "value")
return x
}

x = []
f(x)
print(x) // ["value"]
``````

## »Recursion

A function is allowed to call other functions, including itself. This can be used to implement recursion. For example, the fibonacci sequence is implemented below:

``````fib = func(x) {
if x <= 0 {
return undefined
}

if x == 1 {
return 1
} else {
return x + fib(x - 1)
}
}
``````

Note that this example also shows using undefined as a return value in cases where a function has undefined behavior.