Arbortext Command Language > Using the Arbortext Command Language > User-Defined Functions
  
User-Defined Functions
You can define your own functions using this form:
function name(parameter-list)
{
commands
}
parameter-list can contain up to 50 scalar and array variables that are separated by commas. You declare an array variable by appending brackets ([]) to the variable name.
When a function is called, scalar variables are passed by value, and array arguments are passed by reference. You can force a scalar variable to be passed by reference by adding an ampersand (&) to the variable name. Take this function as an example:
function f(a, &b, c[]) {}
In the example above, the scalar variable "a" is passed by value. The scalar variable "b" and the array variable "c" are passed by reference.
As is the case in C++, you can give trailing arguments default values. Here is an example:
function f(n, m=10) {}
This example declares a function that may be called with one or two arguments. If only one argument is passed, the value of "m" is 10. The default value is an expression that's evaluated at the time of the call. Any variables that are referenced are in the scope of the caller.
The names specified in parameter-list are local to the function. All other variables are global. You can introduce additional local variables by using the local command, as shown in this example:
local x, y=10, z[]
This example declares scalar variables x and y and array variable z to be local to the current block, which ends with a right bracket (]). Scalar variables can be given initial values. In the example above, y has a value of 10. The local command is an executable command, so default values are evaluated each time the command is executed. This also means it's not efficient to use local commands inside loops that are executed many times.
In the C programming language, you can declare a local variable that's already defined at the current level. You cannot do this in ACL. The following example illustrates this point:

function f(x)
{
# illegal, hides parameter
local x;
local m=1
{
# ok
local m=2;
# ok
local x[];
}
# illegal, hides previous value
local m;
}
In ACL, the local command is only allowed inside function definitions.
A function may return a value if the return command, which takes an expression as an optional argument, is used with the function. For example, function fac(n) { return n > 1 ? n * fac(n-1) : 1} is the most common factorial function. If no value is given for the return command, or the function fails to execute a return command, the result of the function is undefined. It's an error to refer to the result of the function in this case.
* 
The return command is also valid inside aliases and source files. In this case, the argument (if any) indicates whether or not the alias or source file succeeds: zero means success, while nonzero means failure.
A function definition must appear at the outermost scope level. That is, you can't define a function inside a function, an alias, or a block. However, it is possible to define a function dynamically using the built-in execute function.
Functions must be defined before they are called. The function command defines the function name after the name argument is parsed. This allows recursive functions to be declared. You can declare a forward reference using this form:
function name () {}
Unlike aliases, the text of the function is not kept in memory, so there is no limit on the size of the function body.
Within a function definition, a variable term in an expression need not start with a dollar sign ($). Here is an example:
function backup_and_save()
{
local bakfile = filename. ".bak"
copy_file $filename $bakfile
save
}
However, the dollar sign is still needed to introduce variable substitution in commands that do not take expressions. The dollar sign is also required in double-quoted strings within expressions.
Also, unlike aliases, you don't have to add execute to commands in which variable substitution is done at parse time. In the example above, an implicit execute is added to the copy_file command, so the values of the variables are not used until run-time.