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

From: Thuna <[email-masked]>
Date: Wed, 14 Aug 2024 16:14:12 +0200

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

No, it is "forms", which is evaluated to obtain a list of forms, each of
which is individually analogous to "form" in `cl-once-only' as used in
the info.  Maybe I have failed to communicate this properly.  Would an
example like

  (cl-defmacro foo ((&rest optforms) body &rest forms)
    (cl-once-only* (all-forms (append optforms forms)) ...))

help?  (I am not sure how I would integrate this into the info but
still.)

>> +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.

Yes, that would work.

>> +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).

Yes, sorry, that was the case in the previous draft but I ended up
missing it when switching from the org document to texi.

>> +@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 [...]

I'll switch to "{First,Second}, ".