Function parameters
Functions can take parameters, to specialize their behavior.
Purpose of function parameters
The function declaration specifies the name of the function and the identifiers of its formal arguments (if any).
Function parameters hold values passed by the caller, to be used in the body of the function.
Function parameter specification with legacy syntax
DEFINE statement that immediately follows the argument
list.FUNCTION check_address(zipcode, street, city)
DEFINE zipcode CHAR(5),
street VARCHAR(100),
city VARCHAR(50)
DEFINE found BOOLEAN -- local function variable
...
END FUNCTIONFunction parameter specification with fully-typed syntax
FUNCTION check_address(zipcode CHAR(5), street VARCHAR(100), city VARCHAR(50))
DEFINE found BOOLEAN -- local function variable
...
END FUNCTIONFunction without parameters
FUNCTION begin_work()
...
END FUNCTIONPassing primitive type values as parameters
Function arguments using simple data types such as INTEGER are passed by value (the values are copied on the stack).
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
Type conversions
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 data type conversions when needed. If the data type conversion is not possible, a runtime error occurs.
NULL
INTEGER:MAIN
CALL add("aaaaa")
END MAIN
FUNCTION add(x)
DEFINE x INTEGER
DISPLAY "x = ", x
END FUNCTIONPassing complex objects as parameters
MAIN
DEFINE ch base.Channel
LET ch = base.Channel.create()
CALL ch.openFile(arg_val(1), "r")
CALL read_lines(ch)
END MAIN
FUNCTION read_lines(ch base.Channel)
DEFINE s STRING
WHILE TRUE
LET s = ch.readLine()
IF ch.isEOF() THEN EXIT WHILE END IF
DISPLAY s
END WHILE
END FUNCTIONPassing records by reference
.* (dot star) notation, records are expanded on the stack: Each field of the record is
passed by value like a primitive data
type:CALL show_cust_info( r_cust.* )INOUT keyword in the
function
definition:FUNCTION init_cust(r CustRec INOUT)
LET r.cust_id = 0
LET r.cust_name = "<undefined>"
LET r.cust_addr = "<undefined>"
LET r.cust_crea = CURRENT
END FUNCTIONINOUT is only supported
when the called function is defined locally, or is known by the compiler because it was imported
with IMPORT FGL.For more details, see Passing records as parameter.