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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.