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

From: Eli Zaretskii <[email-masked]>
Date: Thu, 15 Aug 2024 09:28:35 +0300

> From: Thuna <[email-masked]>
> Cc: [email-masked], [email-masked]
> Date: Thu, 15 Aug 2024 03:05:42 +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?
> >
> > Not really.  What is missing is the explicit statement that FORMS  is
> > evaluated to yield a list of forms.  (Btw, why is it called "FORMS",
> > plural, when it is actually a single form that yields a list of forms
> > only when evaluated?).  The text you wrote:
> >
> >   +Each element of @var{variable} may be used to refer to the result of
> >   +evaluating the corresponding form in @var{forms} within @var{body}.
> >
> > doesn't mention that FORMS is evaluated, and makes it sound like FORMS
> > includes several forms to begin with ("corresponding form in FORMS").
> >
> > This is in direct contradiction with what you explained now, and
> > therefore this text needs to be amended.
> 
> Sorry, this whole thing is a bit confusing due to the layers involved, so let
> me try to explain it again and also try to explain my rationale.  Maybe it
> will answer some of your questions and/or clear up some miscommunication.
> 
> There are three evaluation times here:
> 1. [us] Evaluation of cl-once-only* while macroexpanding (defmacro foo ...)
> 2. [macro author] Evaluation of foo while macroexpanding (foo ...)
> 3. [macro user] Evaluation of the macroexpansion of (foo ...)
> 
> During 1, FORMS is a single form(1) and VARIABLE is a (non-constant)
> symbol(1).
> 
> During 2, this form(1) is evaluated to obtain a list of forms(2), and
> symbol(1) is bound to a list of symbols(2) within BODY.
> 
> During 3, each symbol(2) is bound to the result of evaluating the
> corresponding form(2).
> 
> The macro author interfaces with `cl-once-only*' by passing to it
> - a list of forms(2) which will be evaluated during 3.
> - a symbol(1) which, during 2, will be bound to a list of symbols(2), each of
>   which will hold the value of the corresponding form(2) during 3.
> so from their perspective FORMS is in fact a list of forms.
> 
> While I was writing I was trying to use terms the way a macro author would
> conceptualize, so the name "FORMS" follows from it being a list of forms(2)
> during 2.
> 
> Also, again from the macro author's perspective,
> > corresponding form in FORMS
> > it ... is evaluated to obtain a list of forms
> > FORMS includes several forms to begin with
> ends up reading as
> > corresponding form(2) in [the list of forms(2)]
> > [form(1)] ... is evaluated to obtain [the] list of forms(2)
> > [the list of forms(2)] includes several forms to begin with
> which isn't a contradiction.  I suspect you (understandably) read every `form'
> as form(1), under which interpretation it would indeed be a contradiction.
> 
> I agree that it needs to be mentioned that FORMS is evaluated (during 2).
> I'll probably need to rewrite this thing again, so I'll try to put it in then.

Sorry, I'm now completely confused and bewildered.  Earlier you said
'it is "forms", which is evaluated to obtain a list of forms', now you
seem to be saying that this evaluation is not relevant to the macro
(i.e. is done before the macro is called)?

Anyway, what I'm looking for is not _my_ understanding, but some text
for the manual and the doc strings which will explain this to the
reader.  So maybe suggest text that you think is both accurate and not
supposed to confuse, and let's take it from there.