Estou acostumado com a macro elisp obsoleta flet
e me disseram para mudar para cl-flet
. No entanto, ao fazer essa alteração, alguns dos meus programas elisp pararam de funcionar e percebi que o motivo é que, diferentemente flet
, cl-flet
não permite funções recursivas. Por exemplo, definindo a função abaixo
(defun show-problem-in-action (x)
(cl-flet (
(factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1))) )))
(factorial x) ))
ninguém recebe erro chamando
(show-problem-in-action 0)
Saída: 1
porque a função "cl-flet-defined" factorial
não se chama quando "x = 0". Contudo
(show-problem-in-action 5)
produz o erro void-function factorial
.
Por outro lado, substituindo cl-flet
por sua macro obsoleta flet
, como abaixo
(defun no-problem-with-deprecated-macro (x)
(flet (
(factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1))) )))
(factorial x) ))
permite invocação recursiva:
(no-problem-with-deprecated-macro 5)
Saída: 120
Se cl-flet
não estiver funcionando, qual seria minha melhor alternativa para substituir flet
, ainda sendo capaz de chamar funções recursivamente?
elisp-macros
Ruy
fonte
fonte
flet
ecl-flet
não é a falta de suporte à recursão, mas o fato deflet
fornecer definições de função com escopo dinâmico, enquantocl-flet
fornece definições de função com escopo lexicamente. O escopo dinâmico fornece suporte para recursão em virtude de depender internamente de um indireto.Respostas:
Use em
cl-labels
vez decl-flet
. Para obter uma explicação, consulte o manual do emacsfonte
C-h f cl-flet
que diz "Gostar,cl-labels
mas as definições não são recursivas".flet
ecl-labels
é que as funções definidas com a última sintaxe devem ser mencionadas através da citação # ', em oposição à aspas simples usuais.cl-labels
, como apontado por @phils. Ficarei feliz em excluí-lo, se alguém achar que está usando espaço desnecessário neste fórum.