Declare a user-defined function name and formal parameters

     [STATIC] FUNCTION <idFunction>[(<idParam list>)]
        [LOCAL <identifier> [[:= <initializer>], ... ]]
        [STATIC <identifier> [[:= <initializer>], ... ]]
        [FIELD <identifier list> [IN <idAlias>]]
        [MEMVAR <identifier list>]
        . <executable statements>
        RETURN <exp>


     <idFunction> is the name of the user-defined function to be
     declared.  User-defined function names can be any length, but only the
     first 10 characters are significant.  Names can contain any combination
     of characters, numbers, or underscores, but must begin with a character
     or an underscore.  Leading underscores are not recommended since they
     are reserved for internal functions.

     <idParam list> is the declaration of one or more parameter
     variables.  Variables specified in this list are declared local.

     STATIC FUNCTION declares a user-defined function that can be invoked
     only by procedures and user-defined functions declared in the same
     program (.prg) file.

     LOCAL declares and optionally initializes a list of variables or
     arrays whose visibility and lifetime is the current function.

     STATIC declares and optionally initializes a list of variables or
     arrays whose visibility is the current user-defined function and
     lifetime is the duration of the program.

     FIELD declares a list of identifiers to use as field names whenever
     encountered.  If the IN clause is specified, referring to the declared
     name includes an implicit reference to the specified alias.

     MEMVAR declares a list of identifiers to use as private or public
     memory variables or arrays whenever encountered.

     <identifier> and <identifier list> are labels to be used as
     variable or array names.

     <initializer> is a value to which an array or variable is originally
     set in an inline expression.

     RETURN <exp> passes control back to the calling procedure or
     user-defined function, returning the result of <exp> as the value of the
     function.  Each function must have at least one RETURN statement that
     returns a value.  RETURN statements can occur anywhere in the body of a


     The FUNCTION statement declares a user-defined function and an optional
     list of local variables to receive parameters often referred to as
     formal parameters.  A user-defined function is a subprogram comprised of
     a set of declarations and statements executed whenever you refer to
     <idFunction> followed by an open and closed parentheses pair.  A function
     definition begins with a FUNCTION statement which is the FUNCTION
     declaration and ends with the next FUNCTION statement, PROCEDURE
     statement, or end of file.

     Functions encapsulate a computational block of code and then later
     create expressions using the value returned.  Functions and procedures
     increase both readability and modularity, isolate change, and help
     manage complexity.

     A function in Clipper is the same as a procedure, except that it must
     return a value.  The returned value can be any data type including an
     array, a code block, or NIL.  Each function must begin with a FUNCTION
     statement and contain at least one RETURN statement with an argument.
     Function declarations cannot be nested within other function
     definitions.  A user-defined function can be used wherever standard
     functions are supported, including expressions.

     The visibility of function names falls into two classes.  Functions that
     are visible anywhere in a program are referred to as public functions
     and declared with a FUNCTION statement.  Functions that are visible only
     within the current program (.prg) file are referred to as static
     functions and declared with a STATIC FUNCTION statement.  Static
     functions have filewide scope.

     Static functions limit visibility of a function name, thereby
     restricting access to the function.  Because of this, subsystems defined
     within a single program (.prg) file can provide an access protocol with
     a series of public functions and conceal the implementation details of
     the subsystem within static functions and procedures.  Since the static
     function references are resolved at compile time, they preempt
     references to public functions which are resolved at link time.  This
     ensures that within a program file, a reference to a static function
     executes that function if there is a name conflict with a public

     For more information on user-defined functions, variable declarations,
     and parameter passing, refer to the "Basic Concepts" chapter in the
     Programming and Utilities Guide.


     .  Calling a user-defined function: Use the same notation to call
        a user-defined function as when calling a standard Clipper

        <idFunction>([<argument list>])

        You can call a user-defined function within an expression or on a
        line by itself.  If called on a line by itself, the return value is

        You can also call a user-defined function as an aliased expression by
        prefacing it with an alias and enclosing it in parentheses:

        <idAlias>->(<idFunction>(<argument list>))

        When you call a user-defined function as an aliased expression, the
        work area associated with <idAlias> is selected, the expression is
        executed, and the original work area is then reselected.  You can
        specify an aliased expression on a line by itself, as you would any
        other expression.

        A user-defined function in Clipper may call itself recursively.
        This means you can make a reference to a user-defined function in
        statements or expressions of the same user-defined function

     .  Parameters: User-defined functions, like procedures, can
        receive parameters passed from a calling procedure, user-defined
        function, or DOS command line.  A parameter is a place holder for a
        value or reference.  In Clipper, there are two ways to express
        parameters: you can declare a list of local variable names as a part
        of the FUNCTION declaration (referred to as formal parameters), or
        you can specify a list of private variables in a separate PARAMETERS
        statement.  Note that you cannot mix a declaration of formal
        parameters with a PARAMETERS statement.  Attempting this will result
        in a fatal compiler error.

        Functions receive parameters in the order passed.  In Clipper, the
        number of parameters does not have to match the number of arguments
        passed.  You can skip arguments or omit them from the end of the
        argument list.  A parameter not receiving a value or reference is
        initialized to NIL.  You can skip a parameter by passing NIL.  If
        arguments are specified, PCOUNT() returns the position of the last
        argument passed.  (If more arguments are passed than are parameters,
        they are ignored.)

        Parameters specified in a user-defined function can receive arguments
        passed by value or reference.  The default method for expressions and
        variables is by value.  This includes variables that contain
        references to arrays and objects.  All variables except field
        variables, when prefaced with the pass-by-reference operator (@), are
        passed by reference.  Field variables cannot be passed by reference
        and are always passed by value.


     .  This example demonstrates a user-defined function that formats
        numeric values as currency:

        ? Currency( 1000 )               // Result: $1,000.00

        FUNCTION Currency( nNumber )
           LOCAL cNumber
           IF nNumber < 0
              cNumber := TRANSFORM(-1 * nNumber, ;
              cNumber := PADL("($" + LTRIM(cNumber) + ")", ;
              cNumber := TRANSFORM(nNumber, ;
              cNumber := PADL("$" + LTRIM(cNumber), ;
           RETURN cNumber

     .  This example demonstrates a user-defined function that takes a
        character string formatted as a comma-separated list and returns an
        array with one element per item:

        aList := ListAsArray("One, Two")
        // Result: {"One", "Two"}

        FUNCTION ListAsArray( cList )
           LOCAL nPos
           // Define an empty array
           LOCAL aList := {}
           DO WHILE (nPos := AT(",", cList)) != 0
              // Add a new element
              AADD(aList, SUBSTR(cList, 1, nPos - 1))
              cList := SUBSTR(cList, nPos + 1)
           AADD(aList, cList)
           // Return the array
           RETURN aList

     .  This example checks for a skipped argument by comparing the
        parameter to NIL:

        FUNCTION MyFunc( param1, param2, param3 )
           IF param2 == NIL
              param2 := "default value"
           . <statements>
           RETURN NIL

     .  This example uses the user-defined function, Currency()
        (defined above), as an aliased expression:

        USE Invoices NEW
        USE Customer NEW
        ? Invoices->(Currency(Amount))


7 responses to “C5_FUNCTION

  1. Pingback: C5 Flow Control | Viva Clipper !

  2. Pingback: C5 Statements | Viva Clipper !

  3. Pingback: C5_STATIC | Viva Clipper !

  4. Pingback: C5_RETURN | Viva Clipper !

  5. Pingback: C5_PROCEDURE | Viva Clipper !

  6. Pingback: C5_PARAMETERS | Viva Clipper !

  7. Pingback: C5_LOCAL | Viva Clipper !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.