Zootropo

Diario del mundo geek.

miércoles, mayo 12, 2004

Lisp: Argumentos a funciones

(defun nombre función (arg1 ... argN) ... )

arg1...argN son lo que se llaman argumentos regulares, los típicos de cualquier lenguaje de programación. En Lisp tenemos también lo que llamamos parámetros opcionales.

Argumentos opcionales
(defun nombre función (arg1 ... argN &optional op1 ... opN)

Se colocan siempre primero los argumentos regulares. Los valores que se pasan al llamar a esta función se ligan de izquierda a derecha a los nombres de los parámetros como en cualquier otro lenguaje. Si falta algún valor para opcionales el valor del opcional será nil.

Valores por defecto
(defun nombre función (arg1 ... argN &optional (op1 valor1) ... opM))

Podemos darle un valor por defecto a un argumento opcional, de forma que si no se pasa un valor que se ligue a ese parámetro opcional en lugar de nil se tome como valor el valor por defecto. Para hacer esto como vemos se incluye en una lista el nombre del parámetro y su valor por defecto, que tiene que ser un valor fijo, no puede ser una expresión.

Flag de presencia
(defun nombre función (arg1 ... argN &optional (op1 valor1 op1-provided) ... opM) ...

El flag de presencia evalua a nil si no se pasó un valor para ese parámetro opcional y true si si se le pasó. Nos puede servir por ejemplo en el caso en que el valor por defecto sea nil, en cuyo caso sin este flag no se podría diferenciar entre el caso en que no se especificara ningún valor para ese parámetro o que se especificara pero este fuera nil.

Campos clave
(defun nombre función (arg1 ... argN &key clave1 ... &key claveN) ...

Es similar a los parámetros opcionales pero se le asocia un nombre. En el caso de que tenga muchos parámetros opcionales puedo utilizar los campos clave para asociar un nombre al parámetro opcional en la invocación de la función (en la llamada se usa con :nombre-clave, como si fuera una constante).
Por ejemplo sea el prototipo de la función:

(defun incrementar (n &key operacion &optional (i 1))

Se llamaría a la función asi:

(incrementar 5 :operacion 'inc 7)

Campos clave con valor por defecto
(defun nombre función (arg1 ... argN &key (clave1 valor) ...)

Similar a los opcionales con valor por defecto, la única diferencia entre los argumentos opcionales y los campos clave es que al llamar a la función en los campos clave hay que incuir el nombre del campo.


Como último apunte, si no conocemos el número de parámetros que voy a tener se pueden usar los argumentos de resto:

(defun nombre función (arg1 ... argN &key clave &optional opcional &rest largs)

Todos los parámetros que no se hallan ligado se introducirían en una lista llamada largs.