Macro "cl-flet" que não permite funções recursivas


7

Estou acostumado com a macro elisp obsoleta flete 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-fletnã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" factorialnão se chama quando "x = 0". Contudo

(show-problem-in-action 5)

produz o erro void-function factorial.

Por outro lado, substituindo cl-fletpor 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-fletnão estiver funcionando, qual seria minha melhor alternativa para substituir flet, ainda sendo capaz de chamar funções recursivamente?


4
BTW, a diferença crucial entre flete cl-fletnão é a falta de suporte à recursão, mas o fato de fletfornecer definições de função com escopo dinâmico, enquanto cl-fletfornece 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.
Stefan

Respostas:


4

Use em cl-labelsvez de cl-flet. Para obter uma explicação, consulte o manual do emacs


Ou, de fato, C-h f cl-fletque diz "Gostar, cl-labelsmas as definições não são recursivas".
phils

Obrigado pela resposta. Não seria bom se o aviso que recebi ('flet' é uma macro obsoleta (a partir de 24.3); use 'cl-flet' ou 'cl-letf') também mencionasse 'cl-labels'?
Ruy

Notei (da maneira mais difícil) que outra diferença entre flete cl-labelsé que as funções definidas com a última sintaxe devem ser mencionadas através da citação # ', em oposição à aspas simples usuais.
Ruy

Apesar de minha pergunta ter recebido três votos positivos até agora, estou um pouco envergonhada porque ela pode ser respondida diretamente da sequência de documentos de 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.
Ruy

@ Ruy: não há problema algum. Eu aprendi algo com essa troca e duvido que seja o único.
Dan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.