Subject: bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms

From: Eli Zaretskii <[email-masked]>
Date: Wed, 14 Aug 2024 09:09:04 +0300

> Cc: [email-masked]
> From: Thuna <[email-masked]>
> Date: Wed, 14 Aug 2024 04:21:32 +0200
> 
> Oops, sorry for the bad patch, I've attached the full diff.

Thanks, a few comments about the changes to the manual:

> +@defmac cl-once-only* (variable forms) body
                                   ^^^^^
Shouldn't this be "forms@dots{}"? or maybe "form@dots{}"?

> +This macro is a version of @code{cl-once-only} which takes an
> +arbitrarily long list of forms.  This macro is primarily meant to be
> +used where the number of forms is unknown and thus @code{cl-once-only}
> +cannot work, such as those obtained by a @code{&body} argument.

The last sentence above needs to be restructured.  Perhaps simply move
the "such as" part to the end of the previous sentence.

> +In a call like @code{(my-list ((pop foo) (cl-incf bar) ...) ...)} the
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Such long expressions should be wrapped in @w{..}, to prevent them
from being split between two lines.  Also, please use @dots{} instead
of a literal "..." to generate ellipsis (it will look better in the
printed version of the manual).

> +@code{pop} and @code{cl-incf} will be evaluated exactly once, ensuring
> +their side effects are not applied twice.  This code is however very
> +complex, in the same way code not using @code{cl-once-only} is.
> +
> +Using @code{cl-once-only} is not possible directly due to it expecting
> +individual forms which can be evaluated.  This can be worked around by
> +assigning to a variable @code{`(list ,@@vars)} which @emph{can} be
> +evaluated:
> +
> +@example
> +(defmacro my-list (vals &rest forms)
> +  (cl-once-only ((vals `(list ,@@vals)))
> +    `(list (cl-first ,vals)
> +           (cl-second ,vals)
> +           ,vals                        ; Does not splice
> +           (progn ,@@forms))))
> +@end example
> +
> +There are two problems which both result from the fact that @code{vals}
> +is not a list inside the body of @code{cl-once-only}: 1. @code{vals}
> +cannot be spliced in the way it can in the previous example and
> +2. accessing individual elements of @code{vals} can only be done by
> +accessing the resulting list @emph{during evaluation}.  Compare this to
> +the example using @code{cl-once-only*}:

Please replace "1. " and "2. " with "First, " and "Second, ",
respectively.  Alternatively, if you really want a numbered list, you
could use

 @enumerate
 @item @code{vals} cannot be spliced in the way [...]