Returning records from functions

Returning records as single structured value

Records can be returned from functions and methods as a single structured value, by using only the record name in the RETURNS instruction.

Important:

To return a record as a single structured value, functions must have been defined with the fully typed syntax. Methods for types can only be defined with a fully typed syntax.

For example:
TYPE t_cust RECORD
    pkey INTEGER,
    name VARCHAR(50)
END RECORD

FUNCTION newCustomer() RETURNS t_cust
    DEFINE c t_cust
    LET c.pkey = 0
    LET c.name = "<undefined>"
    RETURN c
END FUNCTION

FUNCTION main()
    DEFINE r t_cust
    LET r = newCustomer()
    DISPLAY r.*
END FUNCTION

This syntax improves code readability and robustness: With the legacy .* notation, the compiler is more permissive and allows to pass and return record members with different types (this is usually done by mistake). When assigning a record without the .* notation from a function return, the compiler produces error -4325, if the types of the target record and the type used in the function RETURNS clause do not match.

Tip:

Another way to return records is is to pass records as reference with the INOUT keyword.

Returning records by expansion (.* notation)

Records can be returned from functions in the RETURN instruction, by expanding the members on the stack, using .* (dot-star) after the record name:
TYPE t_cust RECORD
    pkey INTEGER,
    name VARCHAR(50)
END RECORD

FUNCTION newCustomer()
    DEFINE c t_cust
    LET c.pkey = 0
    LET c.name = "<undefined>"
    RETURN c.*
END FUNCTION

FUNCTION main()
    DEFINE r t_cust
    CALL newCustomer() RETURNING r.*
    DISPLAY r.*
END FUNCTION

Returning records by expansion is supported for backward compatiblity. Consider returning records as a single structured value, without the .* notation, and fully typed function definitions.