# Functions

To define a function:

``foo(x: int): bool := if (x > 10) then true else false``

Usually the return type is optional and can be inferred, e.g. the following function returns a boolean type:

``foo(x: int) := if (x > 10) then true else false``

If the function is recursive the return type must be specified as in:

``fact(x: int) := if (x = 1) then x else x * fact(x - 1) // Type error!fact(x: int): int := if (x = 1) then x else x * fact(x - 1) // OK!``

## Declaration order​

For convenience, functions can be used before their declaration. However, such declarations must be available in the scope and not in inner scopes.

The following is valid (note that g uses f before f is declared):

``g(i: int) := f(i) * 2;k := 1;f(i: int) := i + k;g(1)  // Result is 4``

The following is invalid because the function f is only defined in an inner scope, so it isn’t visible to g.

``g(i: int) := f(i) * 2;k := 1;{    f(i: int) := i + k;    g(1) // Type error!}``

## Anonymous (lambda) functions​

To define anonymous functions:

``\(x: int) -> if (x > 10) then true else false``

If functions have multiple arguments:

``\(x: int, y: string) -> if (x > 10) then y else "smaller"``

To specify the return type of an anonymous function:

``\(x: int): string -> cast((x + 1) as string)``

## Default arguments​

Function definitions can include default arguments but these cannot be followed by non-default arguments, i.e. they must appear at the end.The following is valid:

``inc(n: int, step: int := 1) := a + b;inc(1) // result is 2inc(1, 2) // result is 3inc(1, step:=1) // result is 2``

The following definition is invalid:

``inc(n: int, step: int := 1, v: int) // Error since v is a non-default argument following a default argument``

Functions can be overloaded as long as their types are unambiguous distinct.

Example
``my_sum(x: int, y: int) := x + ymy_sum(x: string, y: string) := x + y``

## Calling functions​

RAW is a functional language, i.e. functions are primary-class citizens in the type system. This means that functions can be stored in collections, passed as arguments, and can be nullable.If a function has a null value, then it cannot be executed. The result of calling it is null, e.g:

``a: function(int, int) := null;a(1) // null``

If one of the arguments of the function is defined as not nullable but caller is passing a nullable value, then the function cannot be executed. In this case, the result of calling it is also null, e.g.:

``inc(v: int not null, step: int not null) := v + step;inc(1, 2) // result is 3inc(null, 2) // result is null``

## Python Functions​

It is possible to create python functions and mix them with RAW’s query language.

### Declaration​

Syntax
``<function name> := \python([<arg name> : <arg type>, ...]): <return type> -> \$\$\$    {python code}\$\$\$``
Example
``foo := \python(x: int): bool -> \$\$\$    if x > 10:        return True    else:        return False\$\$\$;foo(11) // result is true``

NOTE: In python functions definitions, the return type cannot be inferred and is mandatory.