Macro "cl-flet" que no permite funciones recursivas

7

Estoy acostumbrado a la macro elisp en desuso flety 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-fletno 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" factorialno 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-fletpor 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-fletno funciona, ¿cuál sería mi mejor alternativa para reemplazar flet, aún pudiendo llamar a funciones de forma recursiva?

Ruy
fuente
44
Por cierto, la diferencia crucial entre flety cl-fletno es la falta de soporte para la recursividad, sino el hecho de que fletproporciona definiciones de función con ámbito dinámico, mientras que cl-fletproporciona 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.
Stefan

Respuestas:

4

Usar en cl-labelslugar de cl-flet. Para una explicación, mire el manual de emacs

siehe-falz
fuente
O, de hecho, C-h f cl-fletque dice "Me gusta, cl-labelspero las definiciones no son recursivas".
PHILS
Gracias por la respuesta. ¿No sería bueno si la advertencia que recibí ('flet' es una macro obsoleta (a partir de 24.3); use 'cl-flet' o 'cl-letf') también menciona 'cl-labels'?
Ruy
Noté (de la manera difícil) que otra diferencia entre flety cl-labelses que las funciones definidas con la última sintaxis deben referirse a través de la cita # ', en oposición a la comilla simple habitual.
Ruy
A pesar de que mi pregunta obtuvo tres votos cl-labelspositivos 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.
Ruy
@Ruy: no hay problema en absoluto. Yo, por mi parte, aprendí algo de este intercambio, y dudo que sea el único.
Dan