| function-name | 
| (<[([prototype-clause]
                                   [intermediate-result-clause])] | 
| [parameter]
                                   [,[parameter]]
                                   ... >) | 
| [array-index-expression] | 
For an explanation of the symbols used in the syntax diagram, see Syntax Symbols.
Related Statements: DEFINE
                            PROTOTYPE | DEFINE
                            FUNCTION
This document covers the following topics:
A function call invokes a Natural object of the type function.
A function is defined with the DEFINE FUNCTION statement
                       which contains the parameters, local and application-independent variables, the
                       result value to be used and the statements to be executed when the function is
                       called.
               
A function is called by specifying either of the following:
the function name as defined in the DEFINE FUNCTION statement,
                               or
                     
 an alphanumeric variable that contains the name of the function at
                               execution time. In this case, it is necessary to reference the variable in a
                               DEFINE PROTOTYPE
                               statement with the VARIABLE keyword.
                     
A function call can be used within a Natural statement instead of a read-only operand. In this case, the function has to return a result which is then processed by the statement like a field containing the same value.
It is also possible to use a function call in place of a Natural statement. In this case, the function need not return a result value; if returned, the value result is discarded.
Function calls are not allowed in the following situations:
in positions where the operand value is changed by the Natural statement, for example:
MOVE 1 TO #FCT(<..>); 
                     
in a DEFINE
                                     DATA statement;
                     
in a database access statement, such as READ,
                               FIND,
                               SELECT,
                               UPDATE and
                               STORE;
                     
as an argument of Natural system functions, such as
                               AVER,
                               SUM and
                               *TRIM;
                     
in an array index expression;
as a parameter of a function call.
If a function call is used in an INPUT statement, the return value
                       will be treated like a constant value. This leads to an automatic assignment of
                       the attribute
                       AD=O
                       to make this field write-protected (for output only). 
               
Operand Definition Table:
| Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| function-name | S | A | A | U | yes | no | |||||||||||||
Syntax Element Description:
| Syntax Element | Description | 
|---|---|
| function-name | Function Name: 
 
 | 
| prototype-clause | Prototype Clause: | 
| intermediate-result-clause | Intermediate Result Clause: | 
| parameter | Parameter Specification: See  | 
| array-index-expression | Array Index Notation: If the result returned by the function call is an array, an index notation must be provided to address the demanded array occurrences. For details, refer to Index Notation in User-Defined Variables. | 
| PT=prototype-name | 
 Natural requires parameter definitions and the function result to
                        resolve a function call at compile time. If no prototype matches
                        function-name,
                        the parameters or the function result defined for the called function, you can
                        assign a matching prototype with the
                        prototype-clause. In this case, the
                        referenced prototype steps in place and is used to resolve the parameter and
                        function result definitions. The function-name
                        declared in the referenced prototype is ignored. 
               
Syntax Element Description:
| Syntax Element | Description | 
|---|---|
| prototype-name | Prototype Name: 
 
 | 
| IR= | 
 | format-length [/array-definition] | 
 | ||||||
| [(array-definition)] HANDLE OF OBJECT | |||||||||
| ( | 
 | 
 | [/array-definition]) DYNAMIC | ||||||
This clause can be used to specify the
                        format-length/array
                              definition of the result value for a function call if
                        neither the cataloged object of the function nor a prototype definition is
                        available. If a prototype is available for this function call or if a cataloged
                        object of the called function exists, the result value format specified with
                        the intermediate-result-clause is
                        checked for data transfer compatibility. 
               
Syntax Element Description:
| Syntax Element | Description | 
|---|---|
| format-length | Format/Length Definition: The format and length of the field. For information on the format/length definition of user-defined variables; see Format and Length of User-Defined Variables. | 
| array-definition | Array Dimension Definition: With an array-definition, you define the lower and upper bounds of the dimensions in an array definition. See Array Dimension Definition in the Statements documentation. | 
| HANDLE OF
                                        OBJECT | Handle of Object: Used in conjunction with NaturalX. For further information, see NaturalX in the Programming Guide. | 
| A,BorU | Data Format: Possible formats are alphanumeric, binary or Unicode for dynamic variables. | 
| DYNAMIC | Dynamic Variable: A field can be defined as  For further information on processing dynamic variables, see Introduction to Dynamic Variables and Fields. | 
| 
 | n X | 
 | |||||||
| 
 | 
 | 
                                                     | 
 | 
 | |||||
| operand | (AD= | ) | |||||||
You can specify single or multiple parameters to pass data values to the function. They
                              can be provided as constant values or variables, depending on the DEFINE DATA PARAMETER definition
                              within the function. 
               
The semantic and syntactic rules which apply to the function parameters are the same as
                              described in the parameters section of subprograms; see Parameters in
                              the description of the CALLNAT
                              statement.
               
Operand Definition Table:
| Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| operand | C | S | A | G | N * | A | N | P | I | F | B | D | T | L | C | G | O | yes | no | ||
Note
The options marked with an asterisk only apply on Windows and Linux
                                 platforms.
                  
Syntax Element Description:
| Syntax Element | Description | |
|---|---|---|
| nX |  Parameters to be Skipped: With the notation  A parameter that is to be skipped must be defined with the keyword  | |
| AD= |  Attribute Definition: If  | |
| AD=O | Non-modifiable: See session parameter  Note | |
| AD=M | Modifiable: See session parameter  This is the default setting. | |
| AD=A | Input only:  See session parameter  | |
| Note | ||
The example program FUNCEX01 uses the functions
                       F#ADDITION,
                       F#CHAR,
                       F#EVEN and
                       F#TEXT.
               
All example sources shown in this section are provided as source objects and cataloged objects in the Natural SYSEXPG system library.
** Example 'FUNCEX01': Function call  (Program)                         
************************************************************************
DEFINE DATA LOCAL                                                       
  1 #NUM  (I2) INIT <5>                                                 
  1 #A    (I2) INIT <1>                                                 
  1 #B    (I2) INIT <2>                                                 
  1 #C    (I2) INIT <3>                                                 
  1 #CHAR (A1) INIT <'A'>                                               
END-DEFINE                                                              
*                                                                       
IF #NUM = F#ADDITION(<#A,#B,#C>)    /* Function with three parameters.     
  WRITE 'Sum of #A,#B,#C' #NUM                              
ELSE                                                                    
  IF #NUM = F#ADDITION(<1X,#B,#C>)  /* Function with optional parameters.  
    WRITE 'Sum of #B,#C' #NUM                            
  END-IF                                                                
END-IF                                                                  
*                                                                       
DECIDE ON FIRST #CHAR                                                   
  VALUE F#CHAR (<>)(1)             /* Function with result array.         
     WRITE 'Character A found'                                                    
  VALUE F#CHAR (<>)(2)                                                     
     WRITE 'Character B found'                                                     
  NONE                                                                  
     IGNORE                                                             
END-DECIDE                                                              
*                                                                       
IF F#EVEN(<#B>)                    /* Function with logical result value. 
  WRITE #B 'is an even number'                                          
END-IF                                                                  
*                                                                       
F#TEXT(<'Hello', '*'>)             /* Function used as a statement.       
*                                                                      
WRITE F#TEXT(<(IR=A12) 'Good'>)    /* Function with intermediate result.  
*                                                                       
END   
 
                    FUNCEX01Sum of #B,#C      5        
Character A found                             
     2 is an even number            
*** Hello world ***                 
Good morning 
 
                    
                   
               The function F#ADDITION is defined in the example function
                        FUNCEX02. 
               
** Example 'FUNCEX02': Function call  (Function)                        
************************************************************************
DEFINE FUNCTION F#ADDITION                                                    
  RETURNS (I2)                                                          
  DEFINE DATA PARAMETER                                                 
    1 #PARM1 (I2) OPTIONAL                                              
    1 #PARM2 (I2) OPTIONAL                                              
    1 #PARM3 (I2) OPTIONAL                                              
  END-DEFINE                                                            
  /*                                                                    
  RESET F#ADDITION
  IF #PARM1 SPECIFIED                                                   
    F#ADDITION := F#ADDITION + #PARM1                                               
  END-IF                                                                
  IF #PARM2 SPECIFIED                                                   
    F#ADDITION := F#ADDITION + #PARM2                                               
  END-IF                                                                
  IF #PARM3 SPECIFIED                                                   
    F#ADDITION := F#ADDITION + #PARM3                                               
  END-IF                                                                
  /*                                                                    
END-FUNCTION                                                            
*                                                                       
END  
                    
                   
               The function F#CHAR is defined in the example function
                        FUNCEX03. 
               
** Example 'FUNCEX03': Function call (Function) ************************************************************************ DEFINE FUNCTION F#CHAR RETURNS (A1/1:2) /* F#CHAR(1) := 'A' F#CHAR(2) := 'B' /* END-FUNCTION * END
The function F#EVEN is defined in the example function
                        FUNCEX04. 
               
** Example 'FUNCEX04': Function call  (Function)                        
************************************************************************
DEFINE FUNCTION F#EVEN
  RETURNS (L)                                                           
  DEFINE DATA                                                           
  PARAMETER                                                             
    1 #NUM  (N4) BY VALUE                                               
  LOCAL                                                                 
    1 #REST (I2)                                                        
  END-DEFINE                                                            
  /*                                                                    
  DIVIDE 2 INTO #NUM REMAINDER #REST                                    
  /*                                                                    
  IF #REST = 0                                                          
    F#EVEN := TRUE                                                        
  ELSE                                                                  
    F#EVEN := FALSE                                                       
  END-IF                                                                
  /*                                                                    
END-FUNCTION                                                            
*                                                                       
END  
                    
                   
               The function F#TEXT is defined in the example function
                        FUNCEX05 in library SYSEXPG. 
               
** Example 'FUNCEX05': Function call  (Function)                        
************************************************************************
DEFINE FUNCTION F#TEXT
  RETURNS (A20) BY VALUE                                                
  DEFINE DATA                                                           
  PARAMETER                                                             
    1 #TEXT1 (A5) BY VALUE                                                      
    1 #TEXT2 (A1) BY VALUE OPTIONAL                                            
  LOCAL                                                                 
    1 #FRAME (A3)                                                       
  END-DEFINE                                                            
  /*                                                                    
  IF #TEXT2 SPECIFIED                                                   
    MOVE ALL #TEXT2 TO #FRAME                                           
    /*                                                                  
    COMPRESS #FRAME #TEXT1 'world' #FRAME INTO F#TEXT
    /*                                                                  
    WRITE F#TEXT
  ELSE                                                                  
    COMPRESS #TEXT1 'morning' INTO F#TEXT
    /*                                                                  
  END-IF                                                                
  /*                                                                    
END-FUNCTION                                                            
*                                                                       
END  
                    
                  
               According to the function definition, a function call may return a
                       single result field. This can be a scalar value or an array field, which is
                       processed like a temporary field in the statement where the function call is
                       embedded. If the result is an array, the function call must be immediately
                       followed by an array-index-expression
                       addressing the required occurrences. 
               
For example, to access the first occurrence of the array returned:
#FCT(<#A,#B>)(1)
In order to properly resolve a function call at compile time, the compiler requires the format, length and array structure of the parameters and the function result. The parameters specified in the function call are checked against the corresponding definitions in the function to ensure that they match. If a function is used within a statement instead of an operand, the function result must match the format, length and array structure of the operand.
You have three options to provide this information:
Retrieve the parameter and result specifications implicitly from the
                               cataloged object (if available) of the called function if no
                               DEFINE PROTOTYPE
                               statement is executed earlier. 
                     
This method requires the least amount of programming effort.
Use a DEFINE
                                     PROTOTYPE statement. You have to use a DEFINE
                                  PROTOTYPE statement if the cataloged object of the called function is
                               not available or if the function name is not known at compile time, that is,
                               instead of a function name the name of an alphanumeric variable is specified in
                               the function call.
                     
Specify an explicit
                               (IR=)
                               clause in the function call.
                     
The first two methods comprise a full validation of the format, length and array structure of the parameters and the function result.
If neither a DEFINE PROTOTYPE statement nor a cataloged
                        function object exists, you can use the following clauses in your function
                        call:
               
The (IR=)
                                clause specifies the function result format/length/array structure.
                     
This clause determines which format/length/array structure the
                                compiler should assume for the result field (the intermediate result as used by
                                the statement that contains the function call). If a prototype definition is
                                available for a function call, the (IR=) clause overrules the
                                specifications in the prototype. 
                     
 The (IR=) clause does not enforce any parameter
                                checks.
                     
The (PT=) clause uses
                                a previously defined prototype with a name other than the function name. This
                                clause validates the parameters and the function result by using a DEFINE
                                   PROTOTYPE statement with the referenced name.
                     
 In the following example, the function #MULT is called,
                                but the parameter and result specifications from the prototype whose name is
                                #ADD apply:
                     
#I := #MULT(<(PT=#ADD) 2 , 3>)
The first of the following definitions found is used to check the specified parameters:
the prototype definition referenced in the
                                (PT=)
                                clause;
                     
the prototype definition in the DEFINE PROTOTYPE statement
                                where the prototype name matches the function name used in the function
                                call;
                     
 the parameter specifications in the cataloged function object which
                                are supplied with the DEFINE FUNCTION statement.
                     
If none of the above is specified, no parameter validation is performed. This provides you the option to supply any number and layout of parameters in the function call without receiving a syntax error.
The first of the following definitions found is used to check the function result:
the definition provided in the
                                (IR=)
                                clause;
                     
the
                                RETURNS
                                definition in the prototype referenced in the
                                (PT=)
                                clause;
                     
the prototype definition in the DEFINE PROTOTYPE
                                statement where the prototype name matches the function name used in the
                                function call;
                     
the function result specification in the cataloged function object.
If none of the above is specified, a syntax error occurs.
Program:
** Example 'FUNCBX01': Declare result value and parameters  (Program)   
************************************************************************
*                                                                       
DEFINE DATA LOCAL                                                       
  1 #PROTO-NAME (A20)                                                   
  1 #PARM1      (I4)                                                    
  1 #PARM2      (I4)                                                    
END-DEFINE                                                              
*                                                                       
DEFINE PROTOTYPE VARIABLE #PROTO-NAME                                   
  RETURNS (I4)                                                          
  DEFINE DATA PARAMETER                                                 
    1 #P1 (I4) BY VALUE OPTIONAL                                              
    1 #P2 (I4) BY VALUE                                                       
  END-DEFINE                                                            
END-PROTOTYPE                                                           
*                                                                       
#PROTO-NAME := 'F#MULTI'                                                
#PARM1      := 3                                                        
#PARM2      := 5                                                        
*                                                                       
WRITE #PROTO-NAME(<#PARM1, #PARM2>)                                     
WRITE #PROTO-NAME(<1X ,5>)                                              
*                                                                       
WRITE F#MULTI(<(PT=#PROTO-NAME) #PARM1,#PARM2>)                         
*                                                                       
WRITE F#MULTI(<(IR=N20) #PARM1, #PARM2>)                                
*                                                                       
END 
 
                    Function F#MULTI:
               
** Example 'FUNCBX02': Declare result value and parameters  (Function)  
************************************************************************
DEFINE FUNCTION F#MULTI                                                 
  RETURNS #RESULT (I4) BY VALUE                                         
  DEFINE DATA PARAMETER                                                 
    1 #FACTOR1 (I4) BY VALUE OPTIONAL                                            
    1 #FACTOR2 (I4) BY VALUE                                                     
  END-DEFINE                                                            
  /*                                                                    
  IF #FACTOR1 SPECIFIED                                                 
    #RESULT := #FACTOR1 * #FACTOR2                                      
  ELSE                                                                  
    #RESULT := #FACTOR2 * 10                                            
  END-IF                                                                
  /*                                                                    
END-FUNCTION                                                            
*                                                                       
END  
                    
                  
               All function calls used within a Natural statement are evaluated before the statement execution starts. They are evaluated in the same order in which they appear in the statement. Function result values are stored in temporary fields that are later used as operands for execution of the statement.
Calling a function that has modifiable parameters which are repeatedly used within the same statement can cause different function results as indicated in the following example.
Before the COMPUTE statement is started, variable
                        #I has the value 1. In a first step, function
                        F#RETURN is executed. This changes the value of #I to
                        2 and returns a value of 2 as the function result.
                        After this, the COMPUTE operation starts and sums up the values of
                        #I (2) and the temporary field (2) to a value of
                        4. 
               
** Example 'FUNCCX01': Parameter changed within function (Program)      
************************************************************************
DEFINE DATA LOCAL                                                       
  1 #I      (I2) INIT <1>                                               
  1 #RESULT (I2)                                                        
END-DEFINE                                                              
*                                                                       
COMPUTE #RESULT := #I + F#RETURN(<#I>)  /* First evaluate function call, 
                                        /* then execute the addition.    
*                                                                       
WRITE '#I     :' #I /                                                   
      '#RESULT:' #RESULT                                                
*                                                                       
END 
                    ** Example 'FUNCCX02': Parameter changed within function (Function)     
************************************************************************
DEFINE FUNCTION F#RETURN                                                
  RETURNS #RESULT (I2) BY VALUE                                         
  DEFINE DATA PARAMETER                                                 
    1 #PARM1 (I2) BY VALUE RESULT                                       
  END-DEFINE                                                            
  /*                                                                    
  #PARM1  := #PARM1 + 1       /* Increment parameter.                    
  #RESULT := #PARM1           /* Set result value.                      
  /*                                                                    
END-FUNCTION                                                            
*                                                                       
END 
                    FUNCCX01: 
               #I : 2 #RESULT: 4
You can also use a function call in place of a Natural statement without embedding the function call in a statement. In this case, the function call need not return a result value; if returned, the result value is discarded.
You can avoid that such a function call is considered to be part of a
                       previous statement by separating the function call from the previous statement
                       with a semicolon (;) as shown in the following example.
               
Program:
** Example 'FUNCDX01': Using a function as a statement (Program)       
************************************************************************
DEFINE DATA LOCAL                                                       
  1 #A (I4) INIT <1>                                                    
  1 #B (I4) INIT <2>                                                    
END-DEFINE                                                              
*                                                                       
*                                                                       
WRITE 'Write:' #A #B                                                    
F#PRINT-ADD(< 2,3 >)     /* Function call belongs to operand list  
                         /* immediately preceding it.                              
*                                                                       
WRITE // '*************************' //                                 
*                                                                       
WRITE 'Write:' #A #B;    /* Semicolon separates operands and function.      
F#PRINT-ADD(< 2,3 >)     /* Function call does not belong to the         
                         /* operand list.                               
*                                                                       
END 
 
                   Function:
** Example 'FUNCDX02': Using a function as a statement (Function)      
************************************************************************
DEFINE FUNCTION F#PRINT-ADD                                             
  RETURNS (I4)                                                          
  DEFINE DATA PARAMETER                                                 
    1 #SUMMAND1 (I4) BY VALUE                                                    
    1 #SUMMAND2 (I4) BY VALUE                                                    
  END-DEFINE                                                            
  /*                                                                    
  F#PRINT-ADD := #SUMMAND1 + #SUMMAND2    /* Result of function call.    
  WRITE 'Function call:' F#PRINT-ADD                                    
  /*                                                                    
END-FUNCTION                                                            
*                                                                       
END  
                   Output of Program FUNCDX01: 
               
Function call: 5 Write: 1 2 5 ************************* Write: 1 2 Function call: 5