Calling functions
Functions can be invoked, to execute the code they define.
A function can be invoked in different ways:
- with the
CALL
statement, - in an expression, when the function returns a unique value,
- with a callback mechanism like
WHENEVER ERROR CALL
or theINITIALIZER
attribute.
Note: The symbol used to identify the function to be called can be a static function name, or a
variable referencing a function.
For basic data types such as INTEGER
, arguments are passed by value (the value
is copied on the stack) and records, while dynamic arrays and objects are passed by reference (a
handle to the original data is copied on the stack and this allows modification of the original data
inside the function).
In the following code example, the variable x
defined in the
MAIN
block will not be modified by the function:
MAIN
DEFINE x INTEGER
LET x = 123
CALL myfunc(x)
DISPLAY x -- displays 123
END MAIN
FUNCTION myfunc(x)
DEFINE x INTEGER
LET x = x + 1
END FUNCTION
When a function returns a single value, it can be invoked in an
expression:
MAIN
DISPLAY ( 500 + add(50,5) )
END MAIN
FUNCTION add(x,y) RETURNS INTEGER
DEFINE x, y INTEGER
RETURN (x + y)
END FUNCTION
The actual argument in a call to the function need not be of the declared data type of the formal
argument. The runtime system will do the appropriate date type conversions. If data type conversion
is not possible, a runtime error occurs. Note however that for historical reasons, Genero BDL data
type conversion is quite permissive. The following example will not raise an error, because the
string value is silently converted to a
NULL
INTEGER
:MAIN
CALL add("aaaaa")
END MAIN
FUNCTION add(x)
DEFINE x INTEGER
DISPLAY "x = ", x
END FUNCTION
A function can invoke itself
recursively:
MAIN
CALL recursive(1)
END MAIN
FUNCTION recursive(x)
DEFINE x INTEGER
DISPLAY "x = ", x
IF x<10 THEN
CALL recursive(x+1)
END IF
END FUNCTION
A function can be referenced by a variable, and be invoked through this variable in a
CALL
instruction, or in an
expression:TYPE t_func_ref FUNCTION (p1 INT, p2 INT) RETURNS INT
DEFINE fr t_func_ref
LET fr = FUNCTION add -- Function with the same signature as t_func_ref
DISPLAY fr(100,200)