Using types in programs

Define a type as a synonym for an existing data type, or as a shortcut for records and array structures.

After declaring a type, it can be used as a normal data type to define variables.

TYPE t_customer RECORD
         cust_num INTEGER,
         cust_name VARCHAR(50),
         cust_addr VARCHAR(200)
    END RECORD
...
     DEFINE c1 t_customer
...
     DEFINE o1 RECORD
                order_num INTEGER,
                customer t_customer,
                ...
            END RECORD
...
     DEFINE custlist DYNAMIC ARRAY OF t_customer

The scope of a type is the same as for variables and constants. Types can be global, module-specific, or local to a function.

A good practice is to define types that belong to the same domain in a single .4gl module, and import that module in the modules where the types are needed.

By default, module-specific types are private; They cannot be used by an other module of the program. To make a module type public, add the PUBLIC keyword before TYPE. When a module type is declared as public, it can be referenced by another module by using the IMPORT FGL instruction:

-- customers.4gl
PUBLIC TYPE t_ord RECORD
           ord_id INTEGER,
           ord_date DATE,
           ord_total DECIMAL(10,2)
       END RECORD
PUBLIC TYPE t_cust RECORD
           cust_id INTEGER,
           cust_name VARCHAR(50),
           orders DYNAMIC ARRAY OF t_ord,
           ...
       END RECORD
...

-- main.4gl
IMPORT FGL customers
MAIN
    DEFINE custlist DYNAMIC ARRAY OF t_cust
    ...
END MAIN
Types can also used to declare a function signature, in order to define program variables that reference functions with that signature:
TYPE callback_function FUNCTION(p1 INT, p2 INT) RETURNS INT
DEFINE v callback_function
    ...
    LET v = FUNCTION add
    ...