The FUNCTION block defines the body and the signature
(i.e. declaration) of a function. The function declaration specifies
the name of the function and the identifiers of its formal arguments
(if any).
Function names, like other identifiers are case-insensitive. If
the function name is also the name of a built-in function, an
error occurs at link time, even if the program does not reference
the built-in function.
A FUNCTION block cannot appear within the MAIN block,
in a REPORT block, or within another FUNCTION block.
A function can be invoked with the CALL statement,
it can be used in an expression when returning a unique value,
or it can be invoked automatically when registered by a callback
mechanism like WHENEVER ERROR CALL.
If no argument is needed in a function call, an empty argument
list must still be supplied, enclosed between the parentheses.
By default, functions are public; They can be called by any other
module of the program. If a function is only used by the current
module, you may want to hide that function to other modules,
to make sure that it will not be called by mistake. To keep a function
local to the module, add the
PRIVATE keyword
before the function header. Private functions are only hidden
to external modules, all function of the current module can still
call local private functions.
PRIVATE FUNCTION check_number(n)
...
END FUNCTION
The data type of each formal argument of the function must be specified
by a
DEFINE statement that immediately follows
the argument list. The actual argument in a call to the function
need not be of the declared data type of the formal argument.
If data type conversion is not possible, a runtime error occurs.
FUNCTION check_address(zipcode, street, city)
DEFINE zipcode CHAR(5),
street VARCHAR(100),
city VARCHAR(50)
...
END FUNCTION
Function arguments are passed by value (i.e. value is copied on
the stack) for basic data types and records, while dynamic arrays
and objects are passed by reference (i.e. a handle to the original
data is copied on the stack and thus allows modification of the original
data inside the function).
-- The following code is useless:
-- Variable x will not be modified by the function
MAIN
DEFINE x INTEGER
LET x = 123
CALL increment(x)
DISPLAY x -- displays 123
END MAIN
FUNCTION increment(x)
DEFINE x INTEGER
LET x = x + 1
END FUNCTION
Local variables are not visible in other program blocks. The identifiers
of local variables must be unique among the variables that are
declared in the same
FUNCTION definition. Any
global or module variable that has the same identifier as a local
variable, however, is not visible within the scope of the local
variable.
DEFINE x INTEGER -- Declares a module variable
FUNCTION func_a()
DEFINE x INTEGER -- Declares a local variable
LET x = 123 -- Assigns local variable
END FUNCTION
FUNCTION func_b()
LET x = 123 -- Changes the module variable
END FUNCTION
A function that returns one or more values to the calling routine
must include the
return-statement . Values specified
in
RETURN must correspond in number and position,
and must be of the same or of compatible data types , to the variables
in the
RETURNING clause of the
CALL statement.
If the function returns a single value, it can be invoked as
an operand within a expression. Otherwise, you must invoke it
with the
CALL statement with a
RETURNING
clause. An error results if the list of returned values in the
RETURN
statement conflicts in number or in data type with the
RETURNING clause
of the
CALL statement that invokes the
function.
MAIN
DEFINE zipcode CHAR(5),
street VARCHAR(100),
city VARCHAR(50)
CALL get_address() RETURNING zipcode, street, city
END MAIN
FUNCTION get_address()
...
RETURN "23500", "461 Ocean blvd", "Kreistone"
END FUNCTION
A function can invoke itself recursively with a CALL statement.
This will result in a recursive call.