Function statements
This lesson explains the different statements that can be used in internal user-defined functions:
Assignment statement
Assignments in functions are very similar to assignments to discrete variables. For instance:
x := x + 1;
Besides local variables, it is also allowed to assign new values to the parameters. Changes to parameters only have effect inside the function itself.
For multi-assignments, the outer parentheses are not needed:
// Multi-assignment on an edge.
edge do (x, y) := (1, 2);
// Multi-assignment in a function.
x, y := 1, 2;
Return statement
The execution of a function ends when a return
statement is encountered. The value following the return
statement is the result of the entire function. Consider again the return
statement from the mean
function from the previous lesson:
return sum / length;
In this case, the sum
of the input values is divided by the number of input elements (variable length
) to obtain the mean of the input values. The mean of the input values is the result of the function.
While statement
The while
statements allows for repeated execution of the statements in its body, as long as the condition of the while
loop holds. Consider again the mean
function from the previous lesson:
func real mean(list real vs):
int length = size(vs);
int index = 0;
real sum = 0;
while index < length:
sum := sum + vs[index];
index := index + 1;
end
return sum / length;
end
The mean
function processes each of its input values, using a while
loop. As long as the condition (index < length
) holds, the body of the while
is executed over an over. The body consists of two assignments. The first assignment obtains an input value (vs[index]
) and adds it to the sum
. The second statement increases the index, to proceed with the next input value. After the two assignments have been executed, the condition of the while
is evaluated again. If the condition still holds, the two assignments are executed again, etc. When the condition no longer holds, the while
statement is done, and execution proceeds with the next statement, the return
statement.
If statement
In a previous lesson, the if
expression is introduced to construct more complex expressions. Consider the if
expression from that previous lesson, but now used within a function:
func int signum(real x):
return if x > 0: 1
elif x < 0: -1
else 0
end;
end
For functions one can also use if
statements. This expression can be rewritten into an if
statement as follows:
func int signum(real x):
if x > 0:
return 1;
elif x < 0:
return -1;
else
return 0;
end
end
A difference between an if
statement and an if
expression is that the if
statement can be partial in the sense that it does not need an else
part. Consider again the mean
function from above. It does not correctly handle empty lists. The length of an empty list is 0
, so the return
statement will cause a division-by-zero error. We can correctly handle this edge case using an if
statement:
func real mean(list real vs):
int length = size(vs);
int index = 0;
real sum = 0;
if length = 0:
return 0;
end
while index < length:
sum := sum + vs[index];
index := index + 1;
end
return sum / length;
end
Break statement
A break
statement 'jumps out' of a while
statement, continuing with the first statement after the while
. Consider the following CIF specification:
// Get the first 'n' values from 'xs' that are not 'bad'.
func list int first_n(list int xs; int n; int bad):
int index = 0;
int x;
list int result = [];
while index < size(xs):
x := xs[index];
if x != bad:
result := result + [x];
end
if size(result) = n:
break;
end
index := index + 1;
end
return result;
end
// The value of 'y' is [1, 5, 3].
alg list int y = first_n([1, 2, 5, 3, 4, 1, 3], 3, 2);
The first_n
function takes a list of integer numbers xs
, and returns a list result
with the first n
numbers from xs
that are not bad
. A while
loop is used to process each of the numbers in list xs
. The current number is stored in variable x
. If the current number is not the same as bad
, it is added to the result
. If the result
then contains n
values, the break
statement is used to break out of the while
loop and continue execution at the first statement after the while
loop, which is the return
statement. If less than n
values are in the result, index
is incremented to ensure the next number of the list is processed in the next iteration of the while
loop. The return
statement at the end of the function is used to return the result
list, which contains at most n
values.
Continue statement
A continue
statement 'jumps over' the remaining statements in the body of a while
statement, and continues with the next iteration of that while
statement. Consider the following CIF specification:
// Get the values from 'xs' that are greater than 5.
func list int filter_gt5(list int xs):
int index = 0;
int x;
list int result = [];
while index < size(xs):
x := xs[index];
index := index + 1;
if x <= 5:
continue;
end
result := result + [x];
end
return result;
end
// The value of 'y' is [8, 7, 6].
alg list int y = filter_gt5([1, 8, 5, 7, 4, 6, 3]);
The filter_gt5
function takes a list of integer numbers, and returns a filtered list that only contains those integer number that are greater than 5. A while
loop is used to process each of the numbers in list xs
. The current number is stored in variable x
, and index
is incremented to ensure the next number of the list is processed in the next iteration of the while
loop. If the current number is not greater than 5, the remaining statements in the body of the while
are skipped, meaning x
is not added to the result
. The while
loop then continues with the next iteration, for the next number in xs
. If the current number (x
) is greater than 5, execution continues after the if
statement, and the number is added to the result
. After all numbers in the list have been processed, the filtered result
list is returned to the caller of the function.