Function references

Function can be referenced and invoked dynamically in a CALL instruction, or in an expression.

Syntax

A function type is defined with the following syntax:
FUNCTION (
     parameter-name type-specification [ attributes-list ]
     [,...]
  )
 [ attributes-list ]
 [ RETURNS { type-specification [ attributes-list ]
           | ( type-specification [ attributes-list ] [,...] )
           | ( )
           } ]
  1. parameter-name is the name of a formal argument of the function type.
  2. type-specification can be one of:
  3. attributes-list is a comma-separated list of name = value pairs or name attributes, and defines attributes for the function.

Purpose of function references

A function reference points to a function definition, that can be called at runtime. The actual function is not known at compile time, only the function type (number and type of parameters and return values) is known.

This feature allows you to manipulate functions dynamically, for example to implement generic module, that can be configured with callback functions.

Function references are based on function types. Referenced functions must be defined with the syntax defining parameter types in parentheses (and the RETURNS clause, if the functions return values). For more details, see FUNCTION syntax 2.

Defining function types

A function type identifies the signature of a function from the number, names and types of parameters and return values of that function:

FUNCTION(p1 INT, p2 INT) RETURNS INT
Note:

The name of the parameters is part of the function signature. Function types using the same number of parameters/types and return types, but different parameter names are considered as a different function types by the compiler.

A function type can be used as other types, to declare simple variables, members of a structured record, or arrays:
DEFINE fx FUNCTION(p1 INT, p2 INT) RETURNS INT

To simplify function reference usage, define a user-type with the TYPE instruction, with the function type that will match functions to be called by reference:

TYPE callback_function FUNCTION(p1 INT, p2 INT) RETURNS INT

For more details about user-defined type definitions, see Types.

Variable definition for function references

When the user-type for the function reference is available, declare a program variable to hold such function reference:

DEFINE callback callback_function

For more details about variable definitions, see Variables.

Get the FUNCTION reference

To get the reference of a function, use the FUNCTION keyword followed by the name of the function to be referenced. The function must be defined in the current module, or in a module imported with IMPORT FGL.

LET callback = FUNCTION add

In the above example, the function "add()" must be defined with the same function type as the "callback" variable.

For more details, see FUNCTION func-spec.

Invoking a function with the CALL statement

Functions referenced in a variable can be invoked with the CALL instruction, by using the variable. The referenced function will be called as in a regular function call:
CALL callback(100,200) RETURNING result

Using function references in expressions

Variables referencing functions can be used in expressions, like in this example:
LET get_count_func = FUNCTION get_total_items()
LET c = get_count_func()
LET get_count_func = FUNCTION get_total_elements()
LET c = c + get_count_func()

Passing function references as function parameters

Like other values, function references can be passed as function parameters:
CALL process( FUNCTION add, FUNCTION sub, callback )
...
FUNCTION process( f1 callback_function,
                  f2 callback_function,
                  f3 callback_function )
   DISPLAY f1(100,200) + f2(200,50) + f3(150,300)
END FUNCTION