Subject: Re: bug#78995: [PATCH] ;;;autoload-expand for special macros

From: "J.D. Smith" <[email-masked]>
Date: Sun, 13 Jul 2025 15:01:07 -0400

Stefan Monnier <[email-masked]> writes:

>> You'd just need to insert, e.g.:
>>
>>   (put 'defun 'autoload-macroexpand t)
>>
>> where the special macros are _defined_.  This would be a a bit more
>> self-documenting too.
>
> Yes, tho we'd probably define a `declare` thingy so you wouldn't write
> the `put` but you'd write
>
>     (defmacro define-minor-mode ...
>       (declare (...
>                 (autoload macroexpand)

Wow, this is even nicer!  Never knew those `delare's were so simple. 

>> We'd leave the "function-like operator" hard-coded list, but it could
>> probably be trimmed down with the new `autoload-macroexpand' feature.
>> For example, `transient-define-prefix' boils down to a defalias, which
>> is already supported.
>
> Ah, yes, I had not noticed that `transient-define-prefix` had been added
> there, and now that I see it, it does make it seem like my impression
> that it was unimportant may have been wrong.
> Usually macroexpanding those things is enough (the macro can be defined
> appropriately).  We could still refine the above with something like:
>
>     (defmacro transient-define-prefix ...
>       (declare (...
>                 (autoload function)

I mean `defalias' is supported because `defun' expands to it.  Isn't
that enough?  I guess some macros are complex enough you want to take
the quick short cut and turn them right into an `(autoload ...)'
statement, without having to design them carefully?

> tho this probably needs more thought/design because we need more info
> (where's the name of the defined thing, whether it's a macro or
> a function, what's the list of arguments, ...).

The code in `--make-autoload' seems to think it knows how to handle all
those "function-like operators".  But list 1 and list 2 seem to be
disjoint.  E.g. `transient-define-prefix' is on list 2, but _not_ on
list 1.  So it would like to be treated as a function operator, but not
expanded.

Actually I'm confused about that logic.  Take `define-minor-mode'.  It's
on list 1 (expand the macro) and list 2 (treat it as a function
operator).  I don't see how it could ever get list 2 treatment, since it
always would have been expanded first by the list 1 logic above.  There
are many macros in the 1 & 2 category:

   ;; Expand but don't treat as a special function (1, not 2):
   (defun defmacro define-inline
     cl-defgeneric
     cl-defstruct
     pcase-defmacro
     iter-defun
     cl-iter-defun)
   ;; Only treat as a special function op (2, not 1):
   (define-skeleton
     define-derived-mode
     define-compilation-mode
     define-generic-mode
     defun*
     defmacro*
     define-overloadable-function
     transient-define-prefix
     transient-define-suffix
     transient-define-infix
     transient-define-argument)
   ;; Expand _and_ treat as a special function op (1 & 2):
   (define-skeleton
     define-derived-mode
     define-compilation-mode
     define-generic-mode
     easy-mmode-define-global-mode
     define-global-minor-mode
     define-globalized-minor-mode
     easy-mmode-define-minor-mode
     define-minor-mode cl-defun
     defun*
     cl-defmacro
     defmacro*
     define-overloadable-function
     transient-define-prefix
     transient-define-suffix
     transient-define-infix
     transient-define-argument
     defun defmacro define-inline
     cl-defgeneric
     cl-defstruct
     pcase-defmacro
     iter-defun
     cl-iter-defun)

What am I missing?