7

I am used to the deprecated elisp macro flet and I was told to change to cl-flet. However upon making this change some of my elisp programs stopped working and I realized the reason is that, unlike flet, cl-flet does not allow for recursive functions. For example, defining the function below

(defun show-problem-in-action (x)
  (cl-flet (
    (factorial (n)
      (if (= n 0)
        1
        (* n (factorial (- n 1))) )))
  (factorial x) ))

one gets no error by calling

(show-problem-in-action 0)

Output: 1

because the "cl-flet-defined" function factorial does not call itself when "x=0". However

(show-problem-in-action 5)

produces the error void-function factorial.

On the other hand, replacing cl-flet by its deprecated macro flet, such as below

(defun no-problem-with-deprecated-macro (x)
  (flet (
    (factorial (n)
      (if (= n 0)
        1
        (* n (factorial (- n 1))) )))
  (factorial x) ))

allows for recursive invocation:

(no-problem-with-deprecated-macro 5)

Output: 120

If cl-flet is not working, what would be my best alternative to replace flet with, still being able to call functions recursively?

  • 4
    BTW, the crucial difference between flet and cl-flet is not the lack of support for recursion but the fact that flet provides dynamically-scoped function definitions, whereas cl-fletprovides lexically-scoped function definitions. Dynamic scoping happens to provide support for recursion by virtue of relying internally on an indirection. – Stefan Oct 30 '17 at 13:09
4

Use cl-labels instead of cl-flet. For explanation look at the emacs manual

  • Or indeed C-h f cl-flet which says "Like cl-labels but the definitions are not recursive." – phils Oct 30 '17 at 12:32
  • Thanks for the answer. Wouldn't it be nice if the warning I got ('flet' is an obsolete macro (as of 24.3); use either 'cl-flet' or 'cl-letf') also mentioned 'cl-labels'? – Ruy Oct 30 '17 at 13:22
  • I noticed (the hard way) that another difference between flet and cl-labels is that functions defined with the latter syntax must be referred to via the #' quotation, as opposed to the usual single-quote. – Ruy Oct 30 '17 at 18:26
  • Despite the fact that my question got three up-votes so far, I am a bit embarrassed because it can be answered straight from the doc-string of cl-labels, as pointed out by @phils. I'll be glad to delete it should anybody think it is using up unnecessary space in this forum. – Ruy Oct 31 '17 at 12:06
  • @Ruy : no problem at all. I, for one, learned something from this exchange, and I doubt I’ll be the only one. – Dan Nov 1 '17 at 0:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.