FUNCTION
 Declara el nombre y los parámetros formales de una función definida por el
 usuario
------------------------------------------------------------------------------
 Sintaxis

     [STATIC] FUNCTION <idFunción>
        [(<idLista Parámetros>)]
        [LOCAL <identificador> [[:= <inicializador>], ... ]]
        [STATIC <identificador> [[:= <inicializador>], ... ]]
        [FIELD <lista identificadores> [IN <idAlias>]]
        [MEMVAR <lista identificadores>]
        .
        . <sentencias ejecutables>
        .
        RETURN <exp>

 Argumentos

     <idFunción> es el nombre de la función definida por el usuario que
     debe declararse. Los nombres de función definidos por el usuario pueden
     tener cualquier longitud, pero sólo son significativos los primeros 10
     caracteres. Los nombres pueden contener cualquier combinación de
     caracteres, números o signos de subrayado, pero deben comenzar con un
     carácter o signo de subrayado. Los subrayados iniciales no son
     recomendables puesto que están reservados para funciones internas.

     <idLista Parámetros> es la declaración de una o más variables de
     parámetro. Las variables especificadas en esta lista se declaran como
     locales.

     STATIC FUNCTION declara una función definida por el usuario que sólo
     puede llamarse desde procedimientos y funciones definidas por el
     usuario declaradas en el mismo módulo fuente (.prg).

     LOCAL declara y, opcionalmente, inicializa una lista de variables o
     matrices cuya visibilidad y tiempo de vida es la función actual.

     STATIC declara y, opcionalmente, inicializa una lista de variables
     o matrices, cuya visibilidad es la función actual definida por el
     usuario y cuyo tiempo de vida es la duración del programa.

     FIELD declara una lista de identificadores para utilizar como
     nombres de campo siempre que se encuentren. Si se especifica la
     cláusula IN, las referencias al nombre declarado incluyen una
     referencia implícita al alias especificado.

     MEMVAR declara una lista de identificadores para utilizar como
     variables de memoria privadas o públicas o matrices siempre que se
     encuentren.

     <identificador> y <lista identificadores> son etiquetas que
     identifican nombres de variables o matrices.

     <inicializador> es un valor que se asigna originalmente a una
     matriz o variable en una expresión de inicialización en línea.

     RETURN <exp> pasa el control de nuevo al procedimiento o función
     definida por el usuario que la ha llamado, devolviendo el resultado de
     <exp> como valor de retorno de la función. Cada función debe tener,
     como mínimo, una sentencia RETURN que devuelva un valor. Las
     sentencias RETURN pueden colocarse en cualquier parte del cuerpo de una
     función.

 Descripción

     La sentencia FUNCTION declara una función definida por el usuario y una
     lista opcional de variables locales para recibir parámetros, que con
     frecuencia se denominan parámetros formales. Una función definida por
     el usuario es un subprograma compuesto por un conjunto de declaraciones
     y sentencias, que se ejecutan siempre que se hace referencia a
     <idFunción> seguido por un par de paréntesis de apertura y cierre. Una
     definición de función comienza con una sentencia FUNCTION y finaliza
     con la siguiente sentencia FUNCTION o PROCEDURE o el final del
     fichero.

     Las funciones encapsulan un bloque de código de cálculo para después
     crear expresiones utilizando el valor devuelto. Las funciones y
     procedimientos aumentan tanto la legibilidad como la modularidad,
     aislan los cambios y ayudan a manejar situaciones complejas.

     Una función de CA-Clipper es igual que un procedimiento, con la
     excepción de que debe devolver un valor. El valor devuelto puede ser
     cualquier tipo de datos, incluidos una matriz, un bloque de código o
     NIL. Cada función debe comenzar con una sentencia FUNCTION y contener,
     por lo menos, una sentencia RETURN con un argumento. Las declaraciones
     de funciones no pueden anidarse dentro de otras definiciones de
     función. Una función definida por el usuario puede utilizarse
     dondequiera que se admitan funciones estándar, incluyendo expresiones.

     La visibilidad de los nombres de función se divide en dos clases. Las
     funciones que son visibles en cualquier lugar de un programa se
     denominan funciones públicas y se declaran con una sentencia FUNCTION.
     Las funciones que son visibles sólo dentro del módulo fuente actual
     (.prg) se denominan funciones estáticas y se declaran con una
     sentencia STATIC FUNCTION. Las funciones estáticas tienen ámbito de
     módulo.

     Las funciones estáticas limitan la visibilidad de un nombre de función,
     restringiendo por tanto el acceso a las mismas. Por este motivo, los
     subsistemas definidos dentro de un módulo fuente simple (.prg) pueden
     proporcionar un protocolo de acceso con una serie de funciones públicas
     y ocultar los detalles de implantación del subsistema dentro de
     funciones y procedimientos estáticos. Puesto que las referencias de
     función estáticas se resuelven en el tiempo de compilación, éstas se
     apropian de las referencias a las funciones públicas, que se resuelven
     en el tiempo de enlace. Esto garantiza que, dentro de un módulo fuente,
     una referencia a una función estática ejecutará esa función si existe
     un conflicto de nombre con una función pública.

     Para más información sobre funciones definidas por el usuario,
     declaraciones de variables y paso de parámetros, consulte el capítulo
     "Conceptos Básicos" en la Guía de Programación y Utilidades.

 Notas

     ■ Llamada a una función definida por el usuario: Utilice la
        misma notación para llamar a una función definida por el usuario que
        cuando efectúa una llamada a una función de CA-Clipper estándar:

        <idFunción>([<lista argumentos>])

        Puede llamar a una función definida por el usuario dentro de una
        expresión o en una línea, por sí misma. En el segundo caso, el valor
        de retorno se ignora.

        También puede llamar a una función definida por el usuario como una
        expresión de alias, precediéndola con un alias e incluyéndola entre
        paréntesis:

        <idAlias>->(<idFunción>(<lista argumentos>))

        Cuando se llama a una función definida por el usuario como una
        expresión de alias, se selecciona el área de trabajo asociada con
        <idAlias>, la expresión se ejecuta y el área de trabajo original se
        selecciona de nuevo. Puede especificar una expresión de alias en una
        línea, por sí misma, del mismo modo que haría con cualquier otra
        expresión.

        Una función definida por el usuario en CA-Clipper puede llamarse a
        sí misma, repetidamente. Esto significa que puede efectuar una
        referencia a una función definida por el usuario en sentencias o
        expresiones de la propia función.

     ■ Parámetros: Tanto las funciones definidas por el usuario como
        los procedimientos, pueden recibir parámetros pasados por el
        procedimiento o función que los invoca, o desde la línea de mandatos
        del DOS. Un parámetro es un espacio reservado para un valor o una
        referencia. En CA-Clipper, existen dos formas de expresar
        parámetros: puede declarar una lista de nombres de variables locales
        como parte de la declaración FUNCTION (referida como parámetros
        formales) o puede especificar una lista de variables privadas en una
        sentencia PARAMETERS independiente. No puede mezclar una declaración
        de parámetros formales con una sentencia PARAMETERS. Si intenta
        hacerlo de ese modo, se genera un error de compilación.

        Las funciones reciben parámetros en el orden que se les han pasado.
        En CA-Clipper, el número de parámetros no tiene por qué coincidir
        con el número de argumentos pasados. Puede saltarse argumentos u
        omitirlos de la lista de argumentos. Un parámetro que no recibe un
        valor o una referencia se inicializa con NIL. Puede saltarse un
        parámetro pasando NIL. Si se especifican argumentos, PCOUNT()
        devuelve la posición del último argumento pasado. (Si se pasan más
        argumentos que parámetros, son ignorados.)

        Los parámetros especificados en una función definida por el usuario
        pueden recibir argumentos pasados por valor o referencia. El método
        por defecto para expresiones y variables es por valor. Esto incluye
        variables que contienen referencias a matrices y objetos. Todas las
        variables excepto las de campo, cuando están precedidas por el
        operador de paso por referencia (@), se pasan por referencia. Las
        variables de campo no pueden pasarse por referencia y se pasan
        siempre por valor.

 Ejemplos

      Este ejemplo muestra una función definida por el usuario que
        asigna el formato monetario a valores numéricos:

        ? Moneda( 1000 )             // Resultado: $1,000.00

        FUNCTION Moneda( nNumero )
           LOCAL cNumero
           IF nNumero < 0
              cNumero := TRANSFORM(-1 * nNumero, ;
                        "999,999,999,999.99")
              cNumero := PADL("($" + LTRIM(cNumero) + ")", ;
                        LEN(cNumero))
           ELSE
              cNumero := TRANSFORM(nNumero, ;
                        "999,999,999,999.99")
              cNumero := PADL("$" + LTRIM(cNumero), ;
                        LEN(cNumero))
           ENDIF
           RETURN cNumero

      En este ejemplo se muestra una función definida por el usuario
        que toma una cadena de caracteres con formato como una lista
        separada por comas y devuelve una matriz con un elemento por
        objeto:

        aLista := ListaComoMatriz("Uno, Dos")
        // Resultado: {"Uno", "Dos"}

        FUNCTION ListaComoMatriz( cLista )
           LOCAL nPos
           // Definir una matriz vacía
           LOCAL aLista := { }
           //
           DO WHILE (nPos := AT(",", cLista)) != 0
              // Añadir un nuevo elemento
              AADD(aLista, SUBSTR(cLista, 1, nPos - 1))
              cLista := SUBSTR(cLista, nPos + 1)
           ENDDO
           AADD(aLista, cLista)
           //
           // Devolver la matriz
           RETURN aLista

      En este ejemplo se comprueba si se ha saltado algún argumento,
        comparando el parámetro con NIL:

        FUNCTION MiFunc( param1, param2, param3 )
           IF param2 == NIL
              param2 := "valor por defecto"
           ENDIF
           .
           . <sentencias>
           .
           RETURN NIL

      En este ejemplo se utiliza la función definida por el usuario,
        Moneda() (definida anteriormente), como una expresión con alias:

        USE Facturas NEW
        USE Cliente NEW
        ? Facturas->(Moneda(Cantidad))
 To download this example - click here.

See Also: LOCAL PARAMETERS PCOUNT() PRIVATE PROCEDURE RETURN