# Procedures and Functions

Procedures and functions are a lean way of carrying out calculations or algorithms. They do not offer LHS pattern matching. This article provides a description and code examples for both functions and procedures.

Table of Contents

## Functions

A function can be called within your code and must return exactly one parameter. It allows for an arbitrary number of input parameters. Therefore, functions are great for calculating variable values or filling containers. Have a look at the code example below for the specific use of a function and how to declare it.

NOTE: A function always has to return a value and always needs to end with a return statement. However, the return can be empty.

```//Create a function with name fac, input x of type int and a return value of type int
function fac(var x:int) : int {
if(x>1) {
return( x * fac(x-1) );
}
else {
return( 1 );
}
}

//Create a function with input m of type MyNode and return a boolean
function foo(m:MyNode) : boolean {
def var tmp:int = fac(m.myIntAtt);
tmp = tmp - 1;
return( m.myIntAtt < tmp );  //should always return true
}
```

Functions can be called in sequences, rules, other functions, and procedures, as explained in the following examples. Just keep in mind that a function always has to return a value and this value needs to be “assigned” in some way to a variable or attribute when the function is called:

```//Calling a function in a sequence
sequence testSeq1 {
stringvar:string ;>  //Create a string variable
//Assigning the string return value of the function someFunction that has no input arguments
{ stringvar = someFunction() }
}

//Calling a function or a procedure in a rule
rule testRule1 {
n:MyNode;
modify{
eval{
n.myStringAtt = someFunction();
}
}
}

//Calling a function in a function or a procedure
function someFunc1:string{
def var str:string = someFunction();
return(str);
}```

## Procedures

A procedure can be called within your code and must return one or more parameters. It allows for an arbitrary number of input parameters. Use procedures for calculations or complex graph manipulations.  Have a look at the code example below for the specific use of a procedure and how to declare it. Procedures are also used in the BoM-Kit.

NOTE: A procedure may return 0 to k output values.

```//procedure with name foo1, input n of type MyNode and two return values of type MyNode and int
procedure foo1(n:MyNode) : (MyNode,int) {
def m:MyNode;
(m) = add(MyNode);  //create new node of type MyNode and add it to the graph
(def -e:Contains->) = add(Contains,m,n);  //Create Contains edge from node m to n
return(m, n.myIntAtt);  //return the node m and an int attribute value of n
}

//procedure with name bar with no inputs or outputs
procedure bar{
def var total:int;
for(n:MyNode in nodes(MyNode)){  //loop over all MyNode nodes
total = total + n.myIntAtt;  //sum up the myIntAtt value in total
}
(m) = add(MyNode); //create new node of type MyNode and add it to the graph
m.myIntAtt = total;  //write the sum to myIntAtt of m
return;  //empty return statement possible for procedures
}```

Procedures can be called in sequences, rules, functions, and procedures, as explained in the following examples. A procedure can have 0 to many return values. Keep the number of returns in mind when calling a procedure.

```sequence testSeq2 {
stringvar:string ;>  //Create a string variable
//Assigning the return value of procedure someProcedure that has no input arguments
{ (stringvar) = someProcedure() } ;>
{ bar() }  //Calling the procedure bar without an input or return value
}

//The call of procedures in rules, functions, and procedure is equivalent to the call of functions
//please see the example testSeq1 above```

For an overview of different functions and procedures have a look at the Global Functions section.

To see more examples of how to call procedures or functions in sequences please see the Variables in Sequences article.