Statement FUNCTION Foundation

Declares functions with name, formal parameter list and variables.

Syntax
[STATIC] FUNCTION <FunctionName> [( <Parameters,...>  )]
           [LOCAL <VarName_L> [ [:= <Expression>],...]]
          [STATIC <VarName_S> [ [:= <Expression>],...]]
          [MEMVAR <VarName_M,...>]
           [FIELD <FieldName,...> [IN <AliasName>]]
             <SourceCode>
           RETURN <returnValue>
Parameters
STATIC
The STATIC clause limits the visibility of a user-defined function to the PRG file in which the function was declared. Calling the function from another PRG causes a link error.
<FunctionName>
<FunctionName> designates the name of a user-defined function. A function name must consist of alphanumeric characters. The underscore (_) is permitted as a special character, and the first character may not be a numeric character. The first 255 characters of the function, procedure and variable names are significant.
<Parameters,...>
<Parameters,...> is a comma separated list which contains the names of the formal function parameters, which have LOCAL scope. The values passed to the function are assigned to the parameters.
<VarName_L,...>
A list of variables can be optionally declared and initialized with the LOCAL statement. Their visibility and lifetime are limited to the actual function (see the LOCAL statement).
<Expression>
<Expression> can be any legal expression, and it is assigned to the corresponding variable (Initialization) using the inline assignment operator (:=).
<VarName_S,...>
A list of variables can be optionally declared and initialized with the STATIC statement. Their visibility is limited to the actual function, but they remain and retain their values after the termination of the function (see STATIC statement).
<VarName_M,...>
An optional list of PRIVATE or PUBLIC variables may be declared with the MEMVAR statement. They must be subsequently created with the PRIVATE or PUBLIC statement (see the statements PRIVATE and PUBLIC).
<FieldName,...>
With the FIELD statement, an optional list of variables may be declared which belong to the storage class FIELD. The values of field variables are stored in files and their contents remain after the program ends. (see FIELD statement). If the IN option is used, only the fields in the work area designated with <AliasName> are affected.
<returnValue>
The RETURN statement causes the function to end and to pass control back to the calling function or procedure. The value of the expression <returnValue> is returned as the function value. A user-defined function should contain at least one RETURN statement, but can be ended at any point with RETURN. If no RETURN statement is used, a function ends when a new FUNCTION, PROCEDURE, CLASS or METHOD declaration is encountered or when the end of file is reached.
Description

The FUNCTION statement declares a block of program statements as a User-Defined Function (UDF). A UDF is executed when the function name <FunctionName>, followed by parentheses, is specified in the code. Within the parentheses, optional expressions may be supplied. The values of these expressions are passed to the function and assigned to the variables which were declared in the list of formal parameters <Parameters,...>. "Parameter" designates a variable to which a value is assigned by the calling of the function. The passed value is called a function argument. The value of a function parameter is visible within the function as a LOCAL variable.

Functions are used to structure a program and to organize the tasks of a program in components. The basic difference between functions and procedures is that functions have a defined return value, whereas procedures always return the value NIL, which means they have no return value. Functions are introduced by the FUNCTION statement, procedures by the PROCEDURE statement. Both delimit a block of program statements which is executed by using the symbolic name, followed by parentheses. The end of the block of program statements for a function is identified by a new FUNCTION, PROCEDURE, CLASS or METHOD statement or by the end of the source code file. It is considered good programming practice, however, to indicate the end of a function with the RETURN statement.

RETURN passes control back to the calling function or procedure. Multiple RETURN statements can be used within a function or procedure, but it is good programming practice to have only one - at the end of the function or procedure.

The visibility of UDFs can be restricted by the addition of the STATIC keyword. A STATIC FUNCTION is visible only within the PRG file in which it is declared.

User-defined functions follow the same syntactical rules as the Xbase++ functions. They can be called with no argument, multiple arguments or with all declared arguments. When arguments are not passed, the value of the corresponding function parameters within the function call equal NIL. Any validation of the function parameters must be done inside the UDF. A UDF can also be called with an alias operator in front, causing a specific work area to be selected before execution of the function. Arguments are passed to a function by value. When an argument is to be passed by reference, the reference operator @ should be placed in front of the name of the applicable variable. Only character, numeric, logical and date variables can be passed by reference with the reference operator. Arrays and objects are automatically passed by reference.

Examples
FUNCTION declaration and usage
// In the example, the UDF formats a character string so that the first 
// letter is uppercase and the rest are lowercase. 

PROCEDURE Main 
   LOCAL cString 

   USE Customer ALIAS Cust NEW 
   ? UpperLower( "Xbase++" )         // Result: Xbase++ 

                                     // call with alias operator 
   ? Cust->(UpperLower( Name ))      // Result: Kruger 

   cString := "TEST" 
   UpperLower( @cString )            // passing by reference 
   ? cString                         // Result: Test 

RETURN 


FUNCTION UpperLower( cString ) 

   IF Valtype(cString) == "C"        // test of the passed argument 
      cString := ; 
         Upper( Left(cString,1) ) + ; 
         Lower( SubStr(cString,2) ) 
   ENDIF 

RETURN cString                       // return value 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.