# "cl-flet" macro not allowing for recursive functions

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?

• 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-flet`provides lexically-scoped function definitions. Dynamic scoping happens to provide support for recursion by virtue of relying internally on an indirection. Oct 30, 2017 at 13:09

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." 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
Oct 30, 2017 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, 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
Oct 31, 2017 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, 2017 at 0:37