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)
        (* 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)
        (* 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
    Commented Oct 30, 2017 at 13:09

1 Answer 1


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
    Commented Oct 30, 2017 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
    Commented Oct 30, 2017 at 13:22
  • 1
    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
    Commented Oct 30, 2017 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
    Commented Oct 31, 2017 at 12:06
  • 1
    @Ruy : no problem at all. I, for one, learned something from this exchange, and I doubt I’ll be the only one.
    – Dan
    Commented Nov 1, 2017 at 0:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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