Function: cl-labels
cl-labels is an autoloaded macro defined in cl-macs.el.gz.
Signature
(cl-labels ((FUNC ARGLIST BODY...) ...) FORM...)
Documentation
Make local (recursive) function definitions.
BINDINGS is a list of definitions of the form (FUNC ARGLIST BODY...) where FUNC is the function name, ARGLIST its arguments, and BODY the forms of the function body. FUNC is defined in any BODY, as well as FORM, so you can write recursive and mutually recursive function definitions. See info node (cl) Function Bindings for details.
Probably introduced at or before Emacs version 24.3.
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/cl-macs.el.gz
;;;###autoload
(defmacro cl-labels (bindings &rest body)
"Make local (recursive) function definitions.
BINDINGS is a list of definitions of the form (FUNC ARGLIST BODY...) where
FUNC is the function name, ARGLIST its arguments, and BODY the
forms of the function body. FUNC is defined in any BODY, as well
as FORM, so you can write recursive and mutually recursive
function definitions. See info node `(cl) Function Bindings' for
details.
\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
(declare (indent 1) (debug cl-flet))
(let ((binds ()) (newenv macroexpand-all-environment))
(dolist (binding bindings)
(let ((var (make-symbol (format "--cl-%s--" (car binding)))))
(push (cons var (cdr binding)) binds)
(push (cons (car binding)
(lambda (&rest args)
(if (eq (car args) cl--labels-magic)
(list cl--labels-magic var)
(cl-list* 'funcall var args))))
newenv)))
;; Don't override lexical-let's macro-expander.
(unless (assq 'function newenv)
(push (cons 'function #'cl--labels-convert) newenv))
;; Perform self-tail call elimination.
(setq binds (mapcar
(lambda (bind)
(pcase-let*
((`(,var ,sargs . ,sbody) bind)
(`(function (lambda ,fargs . ,ebody))
(macroexpand-all `(cl-function (lambda ,sargs . ,sbody))
newenv))
(`(,ofargs . ,obody)
(cl--self-tco var fargs ebody)))
`(,var (function (lambda ,ofargs . ,obody)))))
(nreverse binds)))
`(letrec ,binds
. ,(macroexp-unprogn
(macroexpand-all
(macroexp-progn body)
newenv)))))