¿Es posible definir dos funciones que se llaman entre sí en Common LISP sin recibir una advertencia de estilo? Mi mejor idea para resolver ese problema es darle a una de esas funciones la segunda como argumento, pero no creo que esa idea sea muy elegante.
3 respuestas
Common Lisp define unidades de compilación , e incluso puede especificar manualmente el alcance de una unidad de compilación utilizando WITH-COMPILATION-UNIT
.
Por ejemplo, cuando llama a COMPILE-FILE
, el archivo completo representa una unidad de compilación: los compiladores generalmente difieren las advertencias al final del archivo, lo que significa que si define correctamente dos funciones recursivas mutuamente, no habrá una advertencia.
Otra posibilidad es realizar una declaración directa:
(declaim (ftype function f))
(defun g () (f))
(defun f () (g))
El primer declaim
indica que f
debe considerarse fbound (el símbolo está enlazado en el espacio de nombres de la función), suprimiendo las advertencias en el punto de uso durante la compilación.
Puede definir dos funciones recursivas mutuamente sin una advertencia de estilo de una manera un poco complicada, dado que defun
no es necesario que aparezca en el nivel superior (consulte Common Lisp the Language, 2nd Edition):
X3J13 votó en marzo de 1989 (DEFINING-MACROS-NON-TOP-LEVEL) para aclarar que, si bien las formas definitorias normalmente aparecen en el nivel superior, es significativo ubicarlas en contextos de nivel no superior;
defun
debe definir la función dentro del entorno léxico adjunto, no dentro del entorno léxico nulo.
Un ejemplo es utilizar el operador especial labels
(manual), que permite la definición de funciones recursivas mutuamente:
CL-USER> (labels ((f (x)
(cond ((> x 0) (g (1- x)))
((= x 0) x)
(t (g (1+ x)))))
(g (y)
(if (= y 0)
0
(f y))))
(defun f(x) (funcall #'f x))
(defun g(x) (funcall #'g x)))
G
CL-USER> (f 3)
0
CL-USER> (g 3)
0
Eso es por supuesto posible. Solo debes tener cuidado de no crear un bucle infinito. Entonces, lo mismo se aplica aquí que para la recursividad (necesita un caso de terminación).
Por cierto, SBCL advierte cuando una función llama a una función indefinida.
Pozdrowienia!
Preguntas relacionadas
Nuevas preguntas
function
Una función (también llamada procedimiento, método, subrutina o rutina) es una parte del código destinada a llevar a cabo una tarea única y específica. Use esta etiqueta para preguntas que impliquen específicamente crear o llamar funciones. Para obtener ayuda para implementar una función para realizar una tarea, utilice [algoritmo] o una etiqueta específica de la tarea en su lugar.