Re: What is the difference between ‘cl-labels’ and ‘named-let’?
Stefan Monnier via Users list for the GNU Emacs text editor <[email protected]>
| Newsgroups | gmane.emacs.help |
|---|---|
| Message-ID | <[email protected]> |
> The Emacs Lisp reference manual does not describe the
> difference between the new-ish (since Emacs 28) ‘named-let’
> and ‘cl-labels’ (other than the syntax, which allows
> ‘cl-labels’ to define many recursive local functions, while
> ‘named-let’ can only define one function per call). Are
> these two different in some significant way?
As it so happens, no: `named-let` is a fairly thin wrapper around
`cl-labels`:
(defmacro named-let (name bindings &rest body)
[...]
(let ((fargs (mapcar (lambda (b) (if (consp b) (car b) b)) bindings))
(aargs (mapcar (lambda (b) (if (consp b) (cadr b))) bindings)))
[...]
`(funcall
(cl-labels ((,name ,fargs . ,body)) #',name)
. ,aargs)))
> The description for ‘named-let’ says that recursive calls in the tail
> position are guaranteed to be optimized tail calls, while the
> description for ‘cl-labels’ does not mention this.
> Is this not the case for ‘cl-labels’, too?
No and yes:
- No, that guarantee does not hold for `cl-labels`.
- Yes, `cl-labels` optimizes tail-calls just as well as `named-let`
(simply because `named-let`s tail-call-optimization is actually
implemented in `cl-labels`), but that covers only those `cl-labels`
that define a single function (hence, it's not guaranteed in general
for `cl-labels`).
> (info "(cl) Function Bindings")
>
> Also, the Emacs Lisp reference manual describes ‘named-let’
> as a special form (like ‘if’), while its docstring describes
> it as a macro. Is this an error in the reference manual?
Sounds like it, yes.
=== Stefan