2.2. Funciones


Una vez conocidos los tipos de datos pasaremos a estudiar cómoutilizarlos. LISP es un lenguaje de programación funcional, es decir quesuministra funciones para la manipulación de los datos.

Los programas LISP se estructuran como formas y funciones.Según Cortés y Sierra*,

una FORMA es "una expresión simbólica enposición de ser evaluada. El cómputo de valores, en LISP, serealiza simplemente mediante la evaluación de una FORMA. Todas lasFORMAS tienen valor, sean estas constantes numéricas, átomosliterales o expresiones simbólicas. Uno de los errores mástípicos al programar en LISP es el de tratar de evaluar una FORMA que notiene valor. El valor de una FORMA es el resultado de evaluarla...
Hay que remarcar que los términos expresión simbólica yFORMA pueden aplicarse a la misma entidad; su aplicacióndependerá del contexto. Una LISTA puede considerarse como un dato, comouna expresión simbólica o considerarse como parte de unprocedimiento; la misma LISTA puede ser considerada como una FORMA" .

Las formas se evalúan (en relación con determinadocontexto) para producir valores y efectos colaterales. Las funciones se invocanaplicándolas a argumentos. (Guy L. Steele Jr.,Common Lisp the Language, capítulo 5). Enel entorno Visual LISP se identifican como FORMAS las funciones de usuariodefinidas dentro de un fichero fuente LSP. Al cargar un programa se recibe laconfirmación de la carga exitosa del mismo mediante el siguientemensaje:

Las funciones son conocidas en matemáticas. Mediante ellas sedescribe algún tipo de relación entre un grupo de valores. Laadición y la multiplicación son funciones simples. Unafunción más compleja sería: f(x)=3x2+2x-15
Esta última función también describe una regla decálculo o algoritmo. Las funciones realizan los cálculos (entérminos LISP, evaluación) utilizando para ello sus argumentos ydevuelven un resultado. A iguales argumentos corresponderán igualesresultados.
Según Cortés y Sierra:

En LISP, los programas se construyen a partir de lacomposición de funciones. Esto permite que tales programas expresen suspropósitos más claramente que los programas convencioneles, y queresulten más fáciles de entender y de mantener, además deser más fáciles de construir.

AutoCAD identifica sus funciones LISP primitivas como el tipo de dato SUBR,mientras que las formas definidas a partir de ellas pertenecen al tipode dato USUBR o "sub-rutina de usuario" La funcióntypedevuelve los tipos correspondientes.La llamada a una función toma la forma de una lista cuyo primer elementoes un átomo simbólico que representa a la función llamada.El resto de los elementos de esa lista pueden ser átomos y otras listas.Estas sublistas se consideran también llamadas a funciones y seevalúan para que su valor resultante pueda ser pasado como argumento ala función que las contiene.

FUNCIONES PRIMITIVAS

Describimos una serie de funciones como ‘primitivas’ en el sentidode que están definidas en la norma del lenguaje, para distinguirlas delas funciones creadas por el usuario a partir de aquéllas. En LISP sellama a una función mediante la siguiente sintaxis:
(NOMBREFUNCION <Argumento_1> ... <Argumento_n>)
La suma de dos números sería (+ 5 1)
Para evaluarla LISP procede de la siguiente manera:
a. Lee la expresión completa (+ 5 1)
b. La interpreta como una llamada a una función y la identifica comoSUMAR <+>
c. Interpreta 5 como primer argumento y 1 como segundo. Elparéntesis de cierre le indica que no hay más argumentos.
d. La función <+> se evalúa para 5 y 1, devolviendo 6 como resultado, que a falta de otro destinoes impreso en pantalla.
Programar LISP significa llamar a funciones. Básicamente esto se haceusando el tipo de dato LISTA. Cualquier lista que no tenga otrainterpretación como forma especialse considerará una llamada a una función, donde el primertérmino se tomará como el nombre de la función y el restocomo sus argumentos. Las listas de llamadas a función pueden estaranidadas, es decir, que una llamada a función se puede estar utilizandocomo argumento en otra lista que corresponda a una llamada a otrafunción. El resultado de la evaluación de cada nivel deanidación es devuelto al nivel de superior, hasta llegar al nivelmás alto, cuyo valor devuelto se imprimiría en la pantalla detexto o la línea de comandos.

ARGUMENTOS FUNCIONALES

De lo expuesto más arriba se concluye que en LISP una funciónes además un objeto de datos que puede ser suministrado a otrafunción como argumento. Esta posibilidad contribuye a la facilidad conque LISP se puede adaptar a las necesidades de cualquier programa mediante laincorporación de nuevas funciones que en su comportamiento resultanidénticas a las primitivas.

Un programa que admite funciones como datos debe también suministraralguna manera de invocarlas. Esto se logra en Visual LISP mediante lafunción APPLY.

APPLY

(apply función lista-args)

APPLY, como su nombre en inglés indica, aplica unafunción (que recibe como primer argumento) a una lista de argumentos. Lafunción puede ser un objeto de código compilado, unaexpresión-lambda, o un símbolo. En este último caso seutiliza el valor funcional global de dicho símbolo, aunque ésteno puede ser una forma especial.

_$ (apply '+ '(2 4 6))
12
_$ (apply '(lambda (x y z)(+ x y z)) '(2 4 6))
12
_$ (apply 'quote '(2 4 6))
; error: bad QUOTE syntax: ((QUOTE 2) (QUOTE 4) (QUOTE 6))
_1$
; reset after error

Obsérvese el error provocado por utilizar la forma especial QUOTE.

Otras muchas funciones LISP requieren argumentos funcionales. Entre las deuso más frecuente están las funciones de mapeado. MAPCAR, porejemplo toma dos o más argumentos: una función y una o máslistas (tantas como parámetros requiera la función) y aplica lafunción sucesivamente a los elementos de cada lista, devolviendo unalista con los resultados.

_$ (mapcar '+ '(1 2 3) '(10 100 1000))
(11 102 1003)

Otras muchas funciones admiten funciones como argumentos. Entre lasmás utilizadas tenemos VL-SORT y VL-REMOVE-IF. La primera es unafunción de ordenación de uso general. Requiere una lista y unpredicado, y devuelve una lista ordenada pasando sus elementos dos a dos alpredicado.

_$ (vl-sort '(3 2 1 3) '<)
(1 2 3)

VL-REMOVE-IF acepta una función y una lista, y devuelve todos loselementos de la lista para los cuales la función devuelva NIL (falso).

_$ (vl-remove-if 'numberp '("a" 3 4 "c" 5 "d" "e"))
("a" "c" "d" "e")

El programar nuevas funciones utilitarias que aceptan argumentos funcionaleses una parte importante del estilo de programación funcional quecaracteriza a LISP.

FUNCIONES ARITMÉTICAS BÁSICAS

Las funciones aritméticas quetienen como argumento un número devuelven distintos valores dependiendode que el argumento proporcionado sea un número entero o real. Si todoslos argumentos son enteros, el valor devuelto será entero. Por elcontrario, si alguno o todos los argumentos son reales, el valor devueltoserá un número real. Por ejemplo:
(/ 12 5) devuelve 2, mientras que (/ 12.0 5) devuelve 2.4
Los argumentos de una función aritmética no son necesariamentenúmeros. Cualquier otra función que devuelva un númerocomo resultado es admisible como argumento de una funciónaritmética. Ejemplo (* (+ 1 5)(- 20 10))

FUNCIONES BÁSICAS DE TRATAMIENTO DE CADENAS

Para el tratamiento de cadenastenemos funciones que permiten unificar cadenas diferentes, extraer subcadenasde una cadena mayor, determinar cuántos caracteres hay en una cadena ytransformar los caracteres a mayúsculas o minúsculas. Elpredicado WCMATCH permite determinar la semejanza de cadenas utiliandocomodines.

FUNCIONES BÁSICAS DE ACCESO A LISTAS

Una lista es una manera de representar un conjunto de átomos y deotras listas. Una lista tiene la forma de un paréntesis de apertura"(" seguido de una serie de átomos o listas, seguidopor otro paréntesis de cierre ")". De manera quecualquier cosa encerrada entre paréntesis será considerada unalista. Una lista pasada al evaluador LISP será tratada como unaexpresión simbólica (S-expresión), es decir, una llamada afunción y se considerará el primer término de la listacomo el nombre de la función. Para que una lista sea tratada como dato yno como una expresión simbólica debe estar contenida en laforma especial QUOTE. Lasfunciones básicas cuyacomprensión es imprescindible para el acceso a la informacióncontenida en listas se pueden reducir a cuatro:QUOTE,CAR,CDR, yNTH.

FUNCIONES DE CONSTRUCCIÓN DE LISTAS

Con las funciones del epígrafe anterior podemos descomponer listas,accediendo a suscomponentes a distintos niveles de anidación. Existenotras funciones que podemosutilizar para componer nuevas listas a base de elementos individuales, ya seanátomos u otras listas. CONS, LIST y APPENDson funciones que construyen listas por distintos procedimientos y conresultados diversos, por lo que es necesario distinguirlas bien.


* Cortés, Ulises y Sierra, Carlos. LISP.Editorial Marcombo, Barcelona-Máxico, 1987. pág. 44
** ibid. pág. 43