Estoy acostumbrado a la macro elisp en desuso flet
y me dijeron que cambiara a cl-flet
. Sin embargo, al hacer este cambio, algunos de mis programas elisp dejaron de funcionar y me di cuenta de que la razón es que, a diferencia flet
, cl-flet
no permite funciones recursivas. Por ejemplo, definiendo la función a continuación
(defun show-problem-in-action (x)
(cl-flet (
(factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1))) )))
(factorial x) ))
uno no recibe ningún error llamando
(show-problem-in-action 0)
Salida: 1
porque la función "cl-flet-defined" factorial
no se llama a sí misma cuando "x = 0". sin embargo
(show-problem-in-action 5)
produce el error void-function factorial
.
Por otro lado, reemplazar cl-flet
por su macro en desuso flet
, como a continuación
(defun no-problem-with-deprecated-macro (x)
(flet (
(factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1))) )))
(factorial x) ))
permite la invocación recursiva:
(no-problem-with-deprecated-macro 5)
Salida: 120
Si cl-flet
no funciona, ¿cuál sería mi mejor alternativa para reemplazar flet
, aún pudiendo llamar a funciones de forma recursiva?
fuente
flet
ycl-flet
no es la falta de soporte para la recursividad, sino el hecho de queflet
proporciona definiciones de función con ámbito dinámico, mientras quecl-flet
proporciona definiciones de función con ámbito léxico. El alcance dinámico proporciona soporte para la recursión en virtud de confiar internamente en una indirección.Respuestas:
Usar en
cl-labels
lugar decl-flet
. Para una explicación, mire el manual de emacsfuente
C-h f cl-flet
que dice "Me gusta,cl-labels
pero las definiciones no son recursivas".flet
ycl-labels
es que las funciones definidas con la última sintaxis deben referirse a través de la cita # ', en oposición a la comilla simple habitual.cl-labels
positivos hasta ahora, estoy un poco avergonzado porque puede responderse directamente desde la cadena de documentos de , como lo señaló @phils. Estaré encantado de eliminarlo si alguien piensa que está usando espacio innecesario en este foro.