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.