Subject: Re: bug#77048: 30.1; Macro `cl-load-time-value` malfunctioning at compile-time and runtime

From: Bohong Huang <[email-masked]>
Date: Wed, 19 Mar 2025 01:26:06 +0800

> I don't see that.  Can you show in detail the steps you go through?
> I did put your file in ~/tmp/foo.el, then byte-compiled it, then did
>
>     emacs -Q -l ~/tmp/foo
>
> then waited a little for the native compiler to kick in, and then
>
>     M-x ltvt-test RET
>
> which did nothing.
> Doing that `M-x` a second time gave me the message "Test message".
> Same thing without native compilation.
>

Interestingly, I can't even byte-compile it (type `B` in Dired), only to
get the following error reported 😢:

   Compiling file /tmp/cl-load-time-value-test.el at Wed Mar 19 01:04:46 2025
   Entering directory ‘/tmp/’

   In ltvt-test:
   cl-load-time-value-test.el:41:4: Warning: reference to free variable
       ‘--cl-load-time--281’
   cl-load-time-value-test.el: Error: End of file during parsing

However, my previous way of reproducing the issue was through
`package-vc-install`, which can be successfully native-compiled.
Confirmed by checking the function's documentation:

   ltvt-test is an autoloaded interactive native-comp-function in
   ‘cl-load-time-value-test.el’.

   (ltvt-test)

   Inferred type: (function nil t)

   Not documented.

   [back]

Yet running the command reports the following error:

   Debugger entered--Lisp error: (void-variable --cl-load-time--0)
     ltvt-test()
     funcall-interactively(ltvt-test)
     command-execute(ltvt-test record)
     execute-extended-command(nil "ltvt-test" nil)
     funcall-interactively(execute-extended-command nil "ltvt-test" nil)
     command-execute(execute-extended-command)

> In my experience, it's always quite easy to rewrite the code without the
> use of `cl-load-time-value` by moving that code outside to some earlier
> `defconst`.  So I do that because I shudder at the idea of relying on
> the hackish implementation of `cl-load-time-value`.  🙂
>
> I think its main use case is in macros where you may not have the
> liberty to move the code to some earlier `defconst`, so you're stuck
> asking `cl-load-time-value` to do it for you.

You're right, but just like this special form is used in Common Lisp,
it's very convenient to wrap a form in `load-time-value` in place to
avoid some repeat evaluations during multiple calls. Perhaps for my
example, I should indeed use `defconst`, while using `eval-when-compile`
for other cases that do not involve function calls in the same file.