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

From: Stefan Monnier <[email-masked]>
Date: Sun, 16 Mar 2025 17:03:56 -0400

> When using `cl-load-time-value` from `cl-lib`, I encountered an issue
> where the macro fails during both byte-compilation and runtime:
>
> `reference to free variable ‘--cl-load-time--0’`  

I tried

    ;; -*- lexical-binding:t -*-
    
    (require 'cl-lib)
    
    (defun my-foo ()
      (time-convert (time-subtract (current-time)
                                   (cl-load-time-value (current-time)))
                    'integer))

and I did get the above warning at compile-time, but it did work
correctly after loading the `.elc` file.
I.e. `M-: (my-foo)` gives me the number of seconds since the file was loaded.

My crystal ball tells me that perhaps you're using `cl-load-time-value`
"at toplevel" rather than within a function?  In that case, indeed,
I think the macro will fail because it relies on

    (defun cl--compiling-top-level-p ()
      "Nil if we're in the middle of byte-compiling something."
      ;; ¡¡Yuck!!
      (not (and (fboundp 'byte-compile-file-form-defmumble)
                ;; FIXME: These are lexical now!
                (boundp 'bytecomp-this-kind) (boundp 'bytecomp-that-one))))

which has stopped working with:

    commit ca1055060d5793e368c1a165c412944d6800c3a6
    Author: Stefan Monnier <[email-masked]>
    Date:   Wed Mar 16 16:08:39 2011 -0400
    
        Remove bytecomp- prefix, plus misc changes.

which made `(bytecomp-)this-kind` into a lexically scoped variable.
So, this is a long-standing bug (of which I've been somewhat aware, as
the FIXME above suggests).
The current implementation of `cl-load-time-value` is fairly
ugly/hackish, so I'd rather not add yet more hideous hacks to it.

> I find this macro is quite useful for performing compile-time
> computations within a function body without polluting global variable
> names and relying on `cl-macrolet`.

Hmm... I don't quite follow: `cl-load-time-value` does not perform
compile-time evaluation but load-time evaluation, as its name suggests.
Maybe you could/should use `eval-when-compile` instead?

Can you show some examples of how you use `cl-load-time-value`?
Maybe some detail may give me an idea how to go about making it work
without making it worse.

        Stefan