Functions
It is often required to execute a bigger part of code repeatedly within the program. In such a case it would be very uncomfortable, if this section needs to be placed at multiple positions in the program code. To avoid this, the programmer has the option to define the code section inside a function that can be called multiple times without much effort. Another advantage is, that changes or corrections in the function code have to be done only once.
A function definition in trCAD code has the following structure:
function identifier ( argument 1, argument 2, ...) { code block }.
The definition tells the system about the function, its name, its arguments and its code block. There must always be a function definition before the function can be used.
The identifier name of the function can be choosen freely with the same limitations that account for variable names: maximum 64 characters of the types 'a'-'z', 'A'-'Z', '0'-'9' and '_'. The identifier mustn't start with a number.
A function can be executed by calling its identifier name followed by the parantheses containing possible arguments. Lets define a simple function and call it two times:
Example
function MyFunction()
{
echo( "The function is executed." );
}
MyFunction()
MyFunction()
Output
The function is executed.
The function is executed.
Note that the code block is not executed the first time when the function is defined. Instead it is executed the two times when the function is called.
Function Arguments
Arguments are used to pass external values into the function. They are placed as variable declarations into the parantheses of the definition and can then be used inside the function code block. Suppose we want to build a function that concatenates a fixed string to another one that shall be passed as an argument:
Example
function MyFunction( string s )
{
echo( "The argument is '" + s + "'." )
}
MyFunction( "Lorem" )
MyFunction( "Ipsum" )
Output
The argument is 'Lorem'.
The argument is 'Ipsum'.
Like in the example, the data type of each argument must be specified within the function definition. Please note that the argument variable lives only inside the function's code block. A variable with the same name may exist outside but this will be a different variable with a value on its onw:
Example
string s = "String 1" // A first variable
function MyFunction( string s ) // The argument is a second variable
{
echo( "The value of 's' inside the function is '" + s + "'." ) // The second variable is used here
}
MyFunction( "String 2" );
echo( "The value of 's' outside the function is '" + s + "'." ) // The first variable is used here
Output
The value of 's' inside the function is 'String 2'.
The value of 's' outside the function is 'String 1'.
There can be an arbitrary number of arguments to the function but they must appear in the same order as in the function definition, seperated by commas:
Example
function MyFunction( string s1, string s2 )
{
echo( "The first argument is '" + s1 + "' and the second one is '" + s2 + "'." )
}
MyFunction( "Lorem", "Ipsum" )
Output
The first argument is 'Lorem' and the second one is 'Ipsum'.
Return Values
In the above examples we used the so-called side effects of function to do some stuff (in the examples cases: to output information about the arguments). Nevertheless we can also use functions in the more "mathematical" way to return a certain value. For that we add the return statement somewhere into the function's code. The return statement has two effects: on one hand, it breaks off the execution of the function immediately. On the other hand a value that is written behind the return keyword is transferred to the "outside" of the function in that the function call is treated as this value. Let's look at this in an example in which a function is used to calculate the squared value of a number:
Example
function Square( int i )
{
return i * i
}
int j = Square( 5 )
echo( j )
Output
25
The return command can also be used without a value after the keyword. It then solely serves as break-off command for the function.
Note
If multiple return commands are used inside a function they must all return values of the same data type. This is required by the system to check the proper use of data types.
Overloading Functions
In some cases it may be desirable to create several functions that do the same thing for different arguments. For means of clarity, it may be useful to name all these functions equally. This is allowed as long as the list of argument differs in (1) the number of arguments or (2) the exact sequence of data types within the list. Then the system can decide by the given argument list which function it should execute. The following example depicts this for three functions:
Example
function MyFunction()
{
echo( "The function without argument was called." )
}
function MyFunction( int i )
{
echo( "The function with integer argument was called." )
}
function MyFunction( string s )
{
echo( "The function with string argument was called." )
}
MyFunction( "string" )
MyFunction()
Output
The function with string argument was called.
The function without argument was called.
Note
trCAD allows function overloading.
Recursive Calls
For some problems it is desirable to call a function from within itself. trCAD owns this ability to perform recursive calls:
Example
function Fibonacci( int i1, int i2 )
{
echo( i1 )
if( i2 < 22 )
Fibonacci( i2, i1 + i2 )
}
Fibonacci( 0, 1 )
Output
0
1
1
2
3
5
8
13
21
Remark
Note that like for loops a badly constructed usage that does not break off runs "forever", freezing the program execution.
Reference arguments
Sometimes returning a single value does not give enough freedom for building a function in a desired way. If two or more values need to be returned, this can be achieved by handing over some arguments by reference.
To explain the difference between "normal" arguments and reference arguments, we need to have a look at what happens when a function is called. In the case of conventional arguments, the argument value is evaluated each time a function is started and a new variable is created that holds this value (i.e. a copy of the parameter). This copied variable is then used during the function execution. Most of the times, this is the desired behavior, e.g. in the above Fibonacci example where all the multiple intermediate values of i1 and i2 are stored implicitly within these temporary copies.
In contrast to that, no copy is created for an argument that is called by reference. In fact, the very variable that gets handed over on calling the functions is used during the function execution. This implies, that if the variable value is changed during a function's execution time, this change is persistent and can be read out after the function has stopped. This can be used to craft additional output channels for a function. The following example shows how a reference argument is defined in the function declaration by setting the '&' character. Then the function is used to return values in two different ways: on one hand it returns a value by a return statement (i.e. with its "normal" return mechanism) and one by its second argument that gets handed over by reference.
Example
function f( int i, int &j )
{
j *= i
return j + 1
}
int m = 5
echo( "f(3," + m + ")=" + f( 3, m ) )
echo( "m=" + m )
Output
f(3,5)=16
m=15
As can be seen, the value of variable m has been changed by the call of f() from 5 to 15, so we created an effective output channel for the function.
Note
Handing over something else than variables or constants currently leads to undefined behavior.