Skip to main content

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 2
inc(1, 2) // result is 3
inc(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

Overloaded functions

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

Example
my_sum(x: int, y: int) := x + y
my_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 3
inc(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.