PreviousNext
Help > BASICS > Identifiers > Functions
Functions

Functions are pieces of code that is called by name and performs some operation. Optionally functions may need to receive some data from the outside world and return some other data back after finishing the operation.

Declaring a function in Rittle is done by using the words: “func” and “endfunc”:

func name;

    ……. something to do …….

    ……. something to do …….

    ……. something to do …….

endfunc;

 

name” is the desired function name. It must be a unique (within the current namespace) and also conform to the requirements of a valid identifier.

Nesting of functions is allowed. In such case the nested function names can be the same if declared in different parent functions:

 

func foo1;

 

            func moo;

    ……. something to do in the function …….

    ……. something to do in the function …….

endfunc;

 

    ……. something else to do …….

 

endfunc;

 

 

func foo2;

 

            func moo;

    ……. something to do in the function …….

    ……. something to do in the function …….

endfunc;

 

    ……. something else to do …….

 

endfunc;

 

In this example both the functions “foo1” and “foo2” contain a nested function “moo”, which may be something completely different in the two cases.

Functions use specially declared local variables to receive data from the caller, or to return data back to the caller. These variables define what type of data is expected, and what role that data plays in the function.

There are three types of role for a local variable: “input”, “output”, and “refer”.

Input role is when the variable takes input from the caller. Data is copied into the local variable and can be used with the body of the function only. The local variable gets destroyed after the function ends.

IMPORTANT! All interface variables “input”, “output”, and “refer” must be declared before calls to other functions.

Output role is when the variable carries something back to the caller. When the function finishes, the caller gets back information from all output variables.

Refer role is more specific. It is bidirectional (serves as input and output at the same time). No actual local variable is created, but instead, the function gains access directly to the variable supplied by the caller. That external variable is just known under the specified local name.

Variables which are passed to functions as refer-type need to be preceded by a ‘@’ character. This instructs the compiler to send to the function a reference to the variable, instead of its data. The same rule is in place for functions passed to func-type variables.

When referring to arrays the variable name must be followed by []. As an example: referring to a single variable “x” would be “@x”, whereas referring to an array with name “x” would be “@x[]”.

It is an important detail to point out that referencing variables always points to the variable itself, but not to a single element in it, in case of arrays. Hence the forms @var (for single variables) and @var[] (for arrays), are valid, but the form @var[index], is not.

So, the bottom line of the roles is: a function may have none or a number of input parameters; may return nothing or several pieces of data to the caller; or may directly read and modify data which belongs to the caller.

In an example:

 

func foo;

 

    var input int a, b, c;

    var output int n, m, p;

    var refer small k;

 

……. something to do in the function …….

……. something to do in the function …….

 

endfunc;

 

This function receives two bytes, returns two bytes, and refers to another byte which belongs to the caller.

Calling functions in Rittle is similar to variable initialisation – a function is called with one or more, or none parameters, and the output is assigned to one or more, or none variables:

var int a,b,c = foo(x,y,@z);

In this case variable “a” will be assigned with the first output variable from function, variable “b” with the second, etc.

In this example the variable “z” is referred to when calling the function.

The number of receiving variables must match or be greater than the number of output variables in the function.

One important feature of this model, is that Rittle allows a single function to behave differently, based on input conditions. For example, a function may have only one fixed input parameter, based on which it may take more input parameters and return different data.

The initialisation statement allows freely mixed constants, variables, and functions:

var int a,b,c = foo(x,y,z), A, 25;

 

The last thing to point out is that Rittle does not require function parameters to be enclosed in brackets. It is up to the user to decide when to use brackets for more clarity in the source. From Rittle’s perspective the two statements

 foo(1,2,3);     and     foo 1,2,3;         … are exactly the same.

 

In some cases, such as during variable initialisation however, brackets may play an important role to tell the compiler what is a parameter to a function, and what is not.