GNU bug report logs - #72344
[PATCH] Add a version of cl-once-only which handles lists of forms

Previous Next

Package: emacs;

Reported by: Thuna <thuna.cing <at> gmail.com>

Date: Sun, 28 Jul 2024 21:18:02 UTC

Severity: wishlist

Tags: patch

Done: Sean Whitton <spwhitton <at> spwhitton.name>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 72344 in the body.
You can then email your comments to 72344 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Sun, 28 Jul 2024 21:18:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Thuna <thuna.cing <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sun, 28 Jul 2024 21:18:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: [PATCH] Add a version of cl-once-only which handles lists of forms
Date: Sun, 28 Jul 2024 23:17:31 +0200
[Message part 1 (text/plain, inline)]
Attached is the macro `cl-once-only*', which takes a symbol which is
bound to a list of form (such as those contained in a `&rest args' in
`defmacro') and binds that variable to a list of symbols where each
symbol is bound to the result of evaluating (in order) the corresponding
form.  The docstring provides an example which might illustrate what it
does better then I did here.

I don't expect this to be used too often but it could be somewhat handy
in macros with a `&rest args' which are supposed to be evaluated.

(My motivation for this is to use this macro in another patch which I
didn't want to make longer with out-of-scope additions.  If this is
considered not worth polluting the `cl-' namespace over I can just write
the forms by hand so it's fine either way.)

[0001-Add-a-version-of-cl-once-only-which-handles-lists-of.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Mon, 29 Jul 2024 00:40:02 GMT) Full text and rfc822 format available.

Message #8 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Thuna <thuna.cing <at> gmail.com>, "72344 <at> debbugs.gnu.org"
 <72344 <at> debbugs.gnu.org>
Subject: RE: [External] : bug#72344: [PATCH] Add a version of cl-once-only
 which handles lists of forms
Date: Mon, 29 Jul 2024 00:39:13 +0000
> Attached is the macro `cl-once-only*', which takes a symbol which is
> bound to a list of form (such as those contained in a `&rest args' in
> `defmacro') and binds that variable to a list of symbols where each
> symbol is bound to the result of evaluating (in order) the corresponding
> form.  The docstring provides an example which might illustrate what it
> does better then I did here.
> 
> I don't expect this to be used too often but it could be somewhat handy
> in macros with a `&rest args' which are supposed to be evaluated.
> 
> (My motivation for this is to use this macro in another patch which I
> didn't want to make longer with out-of-scope additions.  If this is
> considered not worth polluting the `cl-' namespace over I can just write
> the forms by hand so it's fine either way.)

What does this have to do with Common Lisp or its
emulation?

We shouldn't have _any_ functions, vars, macros, ...
whose names use the prefix `cl-' (and not `cl--').
It's really unfortunate that we still do have some.

Using `cl--` (the internal prefix) isn't problematic,
a priori.
___

Just one opinion.







Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Mon, 29 Jul 2024 07:11:01 GMT) Full text and rfc822 format available.

Message #11 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Mon, 29 Jul 2024 16:09:41 +0900
Hello Thuna,

On Sun 28 Jul 2024 at 11:17pm +02, Thuna wrote:

> Attached is the macro `cl-once-only*', which takes a symbol which is
> bound to a list of form (such as those contained in a `&rest args' in
> `defmacro') and binds that variable to a list of symbols where each
> symbol is bound to the result of evaluating (in order) the corresponding
> form.  The docstring provides an example which might illustrate what it
> does better then I did here.
>
> I don't expect this to be used too often but it could be somewhat handy
> in macros with a `&rest args' which are supposed to be evaluated.
>
> (My motivation for this is to use this macro in another patch which I
> didn't want to make longer with out-of-scope additions.  If this is
> considered not worth polluting the `cl-' namespace over I can just write
> the forms by hand so it's fine either way.)

I'm the author of cl-once-only.  I'm interested in macro-writing macros
in the CL tradition.

To be honest, cl-once-only* seems quite esoteric.  Could you perhaps
show me a direct comparison between some cl-once-only code and how it is
made more readable by cl-once-only*?  That seems to me to be the key
criteria.

Also, I wonder if a name like cl-list-once-only would be better.

Thanks!

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Mon, 29 Jul 2024 19:32:02 GMT) Full text and rfc822 format available.

Message #14 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: 72344 <at> debbugs.gnu.org
Subject: RE: [External] : bug#72344: [PATCH] Add a version of cl-once-only
 which handles lists of forms
Date: Mon, 29 Jul 2024 21:30:10 +0200
> What does this have to do with Common Lisp or its
> emulation?

It is not about emulating Common Lisp, but it makes sense to keep this
next to `cl-once-only' as it is a variation of it.

> We shouldn't have _any_ functions, vars, macros, ...
> whose names use the prefix `cl-' (and not `cl--').
> It's really unfortunate that we still do have some.

I assume you mean that the `cl-' prefix should only be for names which
exist in Common Lisp, and while I am sympathetic towards that opinion
`cl-once-only' and `cl-with-gensyms' are macros which are firmly(?)
embedded in cl-lib.  The only other place where they would make sense,
as far as I am aware, is subr or subr-x, but I am not particularly
interested in making and defending the argument that they should be
moved there.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Mon, 29 Jul 2024 19:55:02 GMT) Full text and rfc822 format available.

Message #17 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Thuna <thuna.cing <at> gmail.com>
Cc: "72344 <at> debbugs.gnu.org" <72344 <at> debbugs.gnu.org>
Subject: RE: [External] : bug#72344: [PATCH] Add a version of cl-once-only
 which handles lists of forms
Date: Mon, 29 Jul 2024 19:54:17 +0000
> > What does this have to do with Common Lisp or its
> > emulation?
> 
> It is not about emulating Common Lisp, but it makes sense to keep this
> next to `cl-once-only' as it is a variation of it.
> 
> > We shouldn't have _any_ functions, vars, macros, ...
> > whose names use the prefix `cl-' (and not `cl--').
> > It's really unfortunate that we still do have some.
> 
> I assume you mean that the `cl-' prefix should only be for names which
> exist in Common Lisp, and while I am sympathetic towards that opinion
> `cl-once-only' and `cl-with-gensyms' are macros which are firmly(?)
> embedded in cl-lib.

Yes, my plaint is also for `cl-once-only' and the like.

Firmly?  Those were both just added by Someone(TM)
in Emacs 29 - after _decades_ of Elisp CL emulation.

The original direction/intent of that emulation is
running down the drain - first a drip drip, then a
trickle, soon a steady stream...  Might as well use
prefix `xl-' or `xxl-'.

> The only other place where they would make sense,
> as far as I am aware, is subr or subr-x, but I am not particularly
> interested in making and defending the argument that they should be
> moved there.

As I said, it would be fine to use `cl--' as the
prefix, indicating that it's in some sense "internal".
In this case, at least in the sense that it doesn't
emulate any CL construct.

As I said, just one opinion.  Those who don't care
whether users can tell what's intended to emulate
CL, and what's not, won't agree.

What's not CL emulation is (1) just "plumbing" for
some actual emulation or (2) unrelated stuff that
Someone(TM) thought was clever to add.  Too bad.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Mon, 29 Jul 2024 19:57:01 GMT) Full text and rfc822 format available.

Message #20 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Mon, 29 Jul 2024 21:54:48 +0200
> To be honest, cl-once-only* seems quite esoteric.  Could you perhaps
> show me a direct comparison between some cl-once-only code and how it is
> made more readable by cl-once-only*?  That seems to me to be the key
> criteria.

`cl-once-only*' is meant to work in situations where `cl-once-only' does
not, namely a situation where you do not know the number of forms to be
evaluated.

While such a situation *could* exist without, the cases which benefit
from `cl-once-only*' are overwhelmingly likely to be of the

  (defmacro _ (control &rest args)
    `(progn
       (do-something-with-control ,@args)
       (foo ,@args)))

variety.  The problem here is that the forms in ARGS will be evaluated
twice while we only want it to happen once.  An alternative way to
achieve this would be to do

  (defmacro _ (control &rest args)
    (cl-with-gensyms (argslist)
      `(let ((,argslist (list ,@args)))
         ...)))

and either let-bind ARGS to ARGSLIST or only refer to ARGSLIST within
the body, keeping in mind that ARGSLIST is only a symbol during
macroexpansion and that in order to refer to individual arguments you
need to do (nth N ,ARGSLIST) such that the expanded code itself finds
the relevant argument among all the ones.

With `cl-once-only*', ARGSLIST (or rather ARGS) is not a symbol but a
list of symbols so to refer to the individual argument you do ,(nth N
ARGS) and you can simply wrap your macro which worked (sans the double
evaluating) without the `cl-once-only*' and it should simply* work out of
the box.

(* There is a problem with, say, checking `macroexp-const-p' on the
given arguments, but that is not something that is too difficult to
correct, within reason, and `cl-once-only' doesn't do it either so I
don't think it matters too much.)

> Also, I wonder if a name like cl-list-once-only would be better.

I don't necessarily think that that name is bad but it doesn't quite get
to the heart of the macro either.

The macro is meant to be a `cl-once-only' which works on a list of
forms, and I feel that the "of forms" part is more important than the
"list" part, which is conceptually more likely to take on a meaning of
some ambiguous "collection" rather than a chain of cons cells.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Sat, 03 Aug 2024 02:53:02 GMT) Full text and rfc822 format available.

Message #23 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Sat, 03 Aug 2024 10:51:43 +0800
Hello,

On Mon 29 Jul 2024 at 09:54pm +02, Thuna wrote:

> `cl-once-only*' is meant to work in situations where `cl-once-only' does
> not, namely a situation where you do not know the number of forms to be
> evaluated.
>
> While such a situation *could* exist without, the cases which benefit
> from `cl-once-only*' are overwhelmingly likely to be of the
>
>   (defmacro _ (control &rest args)
>     `(progn
>        (do-something-with-control ,@args)
>        (foo ,@args)))
>
> variety.  The problem here is that the forms in ARGS will be evaluated
> twice while we only want it to happen once.  An alternative way to
> achieve this would be to do
>
>   (defmacro _ (control &rest args)
>     (cl-with-gensyms (argslist)
>       `(let ((,argslist (list ,@args)))
>          ...)))
>
> and either let-bind ARGS to ARGSLIST or only refer to ARGSLIST within
> the body, keeping in mind that ARGSLIST is only a symbol during
> macroexpansion and that in order to refer to individual arguments you
> need to do (nth N ,ARGSLIST) such that the expanded code itself finds
> the relevant argument among all the ones.
>
> With `cl-once-only*', ARGSLIST (or rather ARGS) is not a symbol but a
> list of symbols so to refer to the individual argument you do ,(nth N
> ARGS) and you can simply wrap your macro which worked (sans the double
> evaluating) without the `cl-once-only*' and it should simply* work out of
> the box.

Thanks.  If you have indeed been coming across this in practice, then it
seems worth adding a macro like this.

Btw, I think we would want to see an update to cl.texi along with your
change.

> I don't necessarily think that that name is bad but it doesn't quite get
> to the heart of the macro either.
>
> The macro is meant to be a `cl-once-only' which works on a list of
> forms, and I feel that the "of forms" part is more important than the
> "list" part, which is conceptually more likely to take on a meaning of
> some ambiguous "collection" rather than a chain of cons cells.

I think we should reserve the starred name for now.  As you said, your
macro doesn't come up often, and we might later come up with a variant
of cl-once-only that we want to use very often.

cl-seq-once-only ?

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Sat, 03 Aug 2024 22:42:02 GMT) Full text and rfc822 format available.

Message #26 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Sun, 04 Aug 2024 00:40:22 +0200
[Message part 1 (text/plain, inline)]
> Thanks.  If you have indeed been coming across this in practice, then it
> seems worth adding a macro like this.
>
> Btw, I think we would want to see an update to cl.texi along with your
> change.

I've written a draft for what it could look like.  It needs proofreading
and editing, but it should be a fine-ish place to start from at least.
It uses `cl-once-only*' as the name of the macro but that's just a
placeholder for now.  (Do we want a NEWS entry also?)

I've also made it so that the first argument can either be of the form
(VARIABLE FORMS) or VARIABLE - how it worked before - which stands for
(VARIABLE VARIABLE), so as to keep parity with `cl-once-only'.

I've attached the change to cl.texi and the full implementation of
`cl-once-only*' as a single patch.

>> I don't necessarily think that that name is bad but it doesn't quite get
>> to the heart of the macro either.
>>
>> The macro is meant to be a `cl-once-only' which works on a list of
>> forms, and I feel that the "of forms" part is more important than the
>> "list" part, which is conceptually more likely to take on a meaning of
>> some ambiguous "collection" rather than a chain of cons cells.
>
> I think we should reserve the starred name for now.  As you said, your
> macro doesn't come up often, and we might later come up with a variant
> of cl-once-only that we want to use very often.

I see that point, and it is completely fair.  I have no problem
conceding the starred name.

> cl-seq-once-only ?

How about `cl-once-only-multiple'?  The name should probably be of the
form `cl-once-only<something>', rather than `cl-<something>-once-only' I
think.

[0001-Add-a-version-of-cl-once-only-which-works-on-a-list-.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 06 Aug 2024 01:43:02 GMT) Full text and rfc822 format available.

Message #29 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Tue, 06 Aug 2024 09:41:58 +0800
Hello,

On Sun 04 Aug 2024 at 12:40am +02, Thuna wrote:

> I've written a draft for what it could look like.  It needs proofreading
> and editing, but it should be a fine-ish place to start from at least.
> It uses `cl-once-only*' as the name of the macro but that's just a
> placeholder for now.

Looks good.  I wonder if it might be easier to read if you could somehow
extend the example I used for cl-once-only ?

> (Do we want a NEWS entry also?)

Yes, probably appropriate.

> I've also made it so that the first argument can either be of the form
> (VARIABLE FORMS) or VARIABLE - how it worked before - which stands for
> (VARIABLE VARIABLE), so as to keep parity with `cl-once-only'.

Nice.

>> I think we should reserve the starred name for now.  As you said, your
>> macro doesn't come up often, and we might later come up with a variant
>> of cl-once-only that we want to use very often.
>
> I see that point, and it is completely fair.  I have no problem
> conceding the starred name.

Cool.

>> cl-seq-once-only ?
>
> How about `cl-once-only-multiple'?  The name should probably be of the
> form `cl-once-only<something>', rather than `cl-<something>-once-only' I
> think.

There are already several cl-multiple-... so maybe cl-once-only-mult ?
cl-once-only-multiple is fine with me, though.

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 06 Aug 2024 01:49:02 GMT) Full text and rfc822 format available.

Message #32 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Tue, 06 Aug 2024 09:47:57 +0800
Hello,

On Tue 06 Aug 2024 at 09:41am +08, Sean Whitton wrote:

> There are already several cl-multiple-... so maybe cl-once-only-mult ?
> cl-once-only-multiple is fine with me, though.

cl-once-only-rest, as a reference to &rest ?

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 06 Aug 2024 12:31:02 GMT) Full text and rfc822 format available.

Message #35 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Tue, 06 Aug 2024 14:28:30 +0200
> Looks good.  I wonder if it might be easier to read if you could somehow
> extend the example I used for cl-once-only ?

I'll look into it, though the whole thing really needs a do-over, and I
am not sure if I am the right person for that.  I'll whip up another
draft in a day or so and we can see how that looks.

>> (Do we want a NEWS entry also?)
>
> Yes, probably appropriate.

What about something like this?

  +++
  *** New macro `cl-once-only*'.
  This macro is a version of `cl-once-only' which takes a list of forms.
  This can be used when there are an arbitrary number of arguments which
  need to be evaluated exactly once.

Also, I put it under "Lisp Changes in Emacs" but is that right?

>>> cl-seq-once-only ?
>>
>> How about `cl-once-only-multiple'?  The name should probably be of the
>> form `cl-once-only<something>', rather than `cl-<something>-once-only' I
>> think.
>
> There are already several cl-multiple-... so maybe cl-once-only-mult ?
> cl-once-only-multiple is fine with me, though.
>
> cl-once-only-rest, as a reference to &rest ?

If `cl-once-only-multiple' is fine by you then I would prefer that over
`cl-once-only-rest' and `cl-once-only-mult'.  It would help to get more
suggestions, but I don't think anyone else will be chiming in at this
point.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 06 Aug 2024 12:39:01 GMT) Full text and rfc822 format available.

Message #38 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Tue, 06 Aug 2024 20:37:30 +0800
Hello,

On Tue 06 Aug 2024 at 02:28pm +02, Thuna wrote:

> If `cl-once-only-multiple' is fine by you then I would prefer that over
> `cl-once-only-rest' and `cl-once-only-mult'.  It would help to get more
> suggestions, but I don't think anyone else will be chiming in at this
> point.

It's just really long :)

Let's give ourselves time to think of something shorter.

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 06 Aug 2024 15:54:01 GMT) Full text and rfc822 format available.

Message #41 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>, Thuna <thuna.cing <at> gmail.com>
Cc: "72344 <at> debbugs.gnu.org" <72344 <at> debbugs.gnu.org>
Subject: RE: [External] : bug#72344: [PATCH] Add a version of cl-once-only
 which handles lists of forms
Date: Tue, 6 Aug 2024 15:52:44 +0000
s/cl-/cl--, please.  None of the constructs
mentioned correspond to actual Common Lisp
constructs.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Fri, 09 Aug 2024 05:46:02 GMT) Full text and rfc822 format available.

Message #44 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Fri, 09 Aug 2024 13:44:32 +0800
Hello Thuna,

cl-once-only-many
cl-once-only-these

?

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 13 Aug 2024 21:21:01 GMT) Full text and rfc822 format available.

Message #47 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: 72344 <at> debbugs.gnu.org, drew.adams <at> oracle.com
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Tue, 13 Aug 2024 23:17:41 +0200
[Message part 1 (text/plain, inline)]
>> If `cl-once-only-multiple' is fine by you then I would prefer that over
>> `cl-once-only-rest' and `cl-once-only-mult'.  It would help to get more
>> suggestions, but I don't think anyone else will be chiming in at this
>> point.
>
> It's just really long :)

I do agree that it's decently long, but it's probably fine...?
`cl-destructuring-bind' is the same length and I don't find that too
annoying to write out, though maybe that's just me.

> Let's give ourselves time to think of something shorter.

I don't have any new ideas for the name, but here's a second draft which
tries to adapt the example used in `cl-once-only'.  I was unable to get
the `mapcar' in the first example any more concise, so some thoughts on
rewording and fixing various parts of the text would be nice.

If Drew wants to start a new conversation to move `cl-once-only' (and
also this) out of cl-lib we can also just go with any name now and then
finalize it afterwards, though of all the names the one I favor is still
`cl-once-only-multiple' above all others (sans `cl-once-only*' which is
not an option - unless if you changed your mind about it?).

[cl-texi-second-draft.patch (text/x-patch, inline)]
diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi
index 57e2f3a6c3b..de9f0565d03 100644
--- a/doc/misc/cl.texi
+++ b/doc/misc/cl.texi
@@ -2684,10 +2684,10 @@ Macro-Writing Macros
 @end defmac
 
 @defmac cl-once-only* (variable forms) body
-This macro is a version of @code{cl-once-only} which takes a 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.
+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.
 
 Each element of @var{variable} may be used to refer to the result of
 evaluating the corresponding form in @var{forms} within @var{body}.
@@ -2696,38 +2696,58 @@ Macro-Writing Macros
 such that each form is evaluated in order and its result is bound to the
 corresponding symbol.
 
-Like @code{cl-once-only}, the first argument can be a symbol
-@var{variable}, which is equivalent to writing @code{(variable
-variable)}.
+Like @code{cl-once-only}, the first argument can be a symbol @var{variable}, which
+is equivalent to writing @code{(variable variable)}.
 
 Consider the following macro:
 
 @example
-(defmacro my-list (head &rest args)
-  (cl-once-only ((args `(list ,@@args))
-    `(list (apply #',head ,args)
-           ,args
-           (nth 1 ,args))))
+(defmacro my-list (vals &rest forms)
+  (let ((val-results (mapcar (lambda (_) (gensym)) vals)))
+    `(let* ,(cl-mapcar #'list val-results vals)
+       (list ,(cl-first val-results)
+             ,(cl-second val-results)
+             ,@@val-results
+             (progn ,@@forms)))))
 @end example
 
-This macro is such that it will evaluate @var{args} only once, however
-that @var{args} was a list is lost once we are in @code{cl-once-only}.
-Furthermore, to access any specific element of @var{args} we must obtain
-the element during evaluation via @code{(nth N ,args)}.
+In a call like @code{(my-list ((pop foo) (cl-incf bar) ...) ...)} the
+@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.
 
-Consider the alternative using @code{cl-once-only*}:
+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 (head &rest args)
-  (cl-once-only* args
-    `(list (,head ,@@args)
-           (list ,@@args)
-           ,(nth 1 args))))
+(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*}:
+
+@example
+(defmacro my-list (vals &rest forms)
+  (cl-once-only* vals
+    `(list ,(cl-first vals)
+           ,(cl-second vals)
+           ,@@vals
+           (progn ,@@forms))))
 @end example
 
-which preserves the fact that @var{args} is a list and allows immediate
-access to individual arguments by simply choosing the corresponding
-element in @var{args}.
+which preserves the fact the @var{vals} is a list and removes
+boiler-plate code for generating and assigning temporary variables.
 @end defmac
 
 @node Macros

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 13 Aug 2024 21:37:02 GMT) Full text and rfc822 format available.

Message #50 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Thuna <thuna.cing <at> gmail.com>, Sean Whitton <spwhitton <at> spwhitton.name>
Cc: "72344 <at> debbugs.gnu.org" <72344 <at> debbugs.gnu.org>
Subject: RE: [External] : Re: bug#72344: [PATCH] Add a version of cl-once-only
 which handles lists of forms
Date: Tue, 13 Aug 2024 21:36:08 +0000
> If Drew wants to start a new conversation to move `cl-once-only' (and
> also this) out of cl-lib we can also just go with any name now and then
> finalize it afterwards, though of all the names the one I favor is still
> `cl-once-only-multiple' above all others (sans `cl-once-only*' which is
> not an option - unless if you changed your mind about it?).

I've said all I have to say on the matter.
I seem to be a minority of one, and won't
bother starting any new thread about it.

I will however, repeat it here, for the record.

We've deviated from prefix cl- being only for
emulations of Common Lisp constructs.  At
first just a little, but more and more over
time.  I really don't see the point of that.
And I've never heard any good reason for it.

I understand that cl- is a library prefix,
so the functions etc. defined there should
take the library prefix.

What I object to is adding non-internal
constructs to this library that aren't
part of Common Lisp (and are generally not
even related).

I have no objection to using prefix cl--
(internal prefix) for utility functions &
macros in the library - i.e., for plumbing
needed to support the actual emulation.

Since the point of the library is (used to
be, at least) ONLY to emulate CL constructs,
I think cl- should be reserved for those
constructs, and anything else in it should
use cl--.

Yes, that would mean moving un-CL functions
etc. out of the library, to somewhere else.
And yes, that would mean replacing their
cl- prefix with whatever prefix is right
for their new location.  And enforce the
rule thereafter that you don't get to add
wonderful-whatever-function to the library
and give it prefix cl-.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 13 Aug 2024 22:21:02 GMT) Full text and rfc822 format available.

Message #53 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: 72344 <at> debbugs.gnu.org, Sean Whitton <spwhitton <at> spwhitton.name>
Subject: RE: [External] : Re: bug#72344: [PATCH] Add a version of
 cl-once-only which handles lists of forms
Date: Wed, 14 Aug 2024 00:18:39 +0200
>> If Drew wants to start a new conversation to move `cl-once-only' (and
>> also this) out of cl-lib we can also just go with any name now and then
>> finalize it afterwards, though of all the names the one I favor is still
>> `cl-once-only-multiple' above all others (sans `cl-once-only*' which is
>> not an option - unless if you changed your mind about it?).
>
> I've said all I have to say on the matter.  I seem to be a minority of
> one, and won't bother starting any new thread about it.

I don't know what the overall opinion is, but I do not necessarily
disagree with you that cl-lib should be for (and only for) emulating
Common Lisp.  While I do not know the scope and extent of the changes
you want to make, I support moving with-gensyms and once-only (and
consequently this) out of cl-lib.  However I simply do not have the
energy to start (more) arguments and try to convince people to make this
change.

> I have no objection to using prefix cl-- (internal prefix) for utility
> functions & macros in the library - i.e., for plumbing needed to
> support the actual emulation.

When talking about this patch in a vacuum, I am vehemently opposed to
using the `cl--' prefix - this macro is a public-facing one, and making
it internal is a guaranteed way to make sure no one uses it.  It also
does not make sense that this macro (and only this macro) should be left
out of cl-lib, since this is a near-identical version of `cl-once-only'
with minor changes.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Tue, 13 Aug 2024 22:59:01 GMT) Full text and rfc822 format available.

Message #56 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Thuna <thuna.cing <at> gmail.com>
Cc: "72344 <at> debbugs.gnu.org" <72344 <at> debbugs.gnu.org>,
 Sean Whitton <spwhitton <at> spwhitton.name>
Subject: RE: [External] : Re: bug#72344: [PATCH] Add a version of cl-once-only
 which handles lists of forms
Date: Tue, 13 Aug 2024 22:57:21 +0000
> >> If Drew wants to start a new conversation to move `cl-once-only' (and
> >> also this) out of cl-lib we can also just go with any name now and
> then
> >> finalize it afterwards, though of all the names the one I favor is
> still
> >> `cl-once-only-multiple' above all others (sans `cl-once-only*' which
> is
> >> not an option - unless if you changed your mind about it?).
> >
> > I've said all I have to say on the matter.  I seem to be a minority of
> > one, and won't bother starting any new thread about it.
> 
> I don't know what the overall opinion is, but I do not necessarily
> disagree with you that cl-lib should be for (and only for) emulating
> Common Lisp.  While I do not know the scope and extent of the changes
> you want to make, I support moving with-gensyms and once-only (and
> consequently this) out of cl-lib.  However I simply do not have the
> energy to start (more) arguments and try to convince people to make this
> change.

Understood.  Thanks for your consideration.

> > I have no objection to using prefix cl-- (internal prefix) for utility
> > functions & macros in the library - i.e., for plumbing needed to
> > support the actual emulation.
> 
> When talking about this patch in a vacuum, I am vehemently opposed to
> using the `cl--' prefix - this macro is a public-facing one, and making
> it internal is a guaranteed way to make sure no one uses it.  It also
> does not make sense that this macro (and only this macro) should be left
> out of cl-lib, since this is a near-identical version of `cl-once-only'
> with minor changes.

Also understood.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Wed, 14 Aug 2024 00:03:01 GMT) Full text and rfc822 format available.

Message #59 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org, Drew Adams <drew.adams <at> oracle.com>
Subject: Re: [External] : Re: bug#72344: [PATCH] Add a version of
 cl-once-only which handles lists of forms
Date: Wed, 14 Aug 2024 08:01:16 +0800
Hello,

On Wed 14 Aug 2024 at 12:18am +02, Thuna wrote:

>>> If Drew wants to start a new conversation to move `cl-once-only' (and
>>> also this) out of cl-lib we can also just go with any name now and then
>>> finalize it afterwards, though of all the names the one I favor is still
>>> `cl-once-only-multiple' above all others (sans `cl-once-only*' which is
>>> not an option - unless if you changed your mind about it?).
>>
>> I've said all I have to say on the matter.  I seem to be a minority of
>> one, and won't bother starting any new thread about it.
>
> I don't know what the overall opinion is, but I do not necessarily
> disagree with you that cl-lib should be for (and only for) emulating
> Common Lisp.  While I do not know the scope and extent of the changes
> you want to make, I support moving with-gensyms and once-only (and
> consequently this) out of cl-lib.  However I simply do not have the
> energy to start (more) arguments and try to convince people to make this
> change.

They were quite deliberately put under cl-, actually, when I added them.

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Wed, 14 Aug 2024 00:07:02 GMT) Full text and rfc822 format available.

Message #62 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org, drew.adams <at> oracle.com
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Wed, 14 Aug 2024 08:05:57 +0800
Hello,

On Tue 13 Aug 2024 at 11:17pm +02, Thuna wrote:

>>> If `cl-once-only-multiple' is fine by you then I would prefer that over
>>> `cl-once-only-rest' and `cl-once-only-mult'.  It would help to get more
>>> suggestions, but I don't think anyone else will be chiming in at this
>>> point.
>>
>> It's just really long :)
>
> I do agree that it's decently long, but it's probably fine...?
> `cl-destructuring-bind' is the same length and I don't find that too
> annoying to write out, though maybe that's just me.

You're not keen on either of my other suggestions, right?

    cl-once-only-many, cl-once-only-these

I guess I am hung up on how -multiple- is already used in CL names, but
it comes *before* the things that are multiple.  But I believe you don't
like cl-multiple-once-only.

> I don't have any new ideas for the name, but here's a second draft which
> tries to adapt the example used in `cl-once-only'.  I was unable to get
> the `mapcar' in the first example any more concise, so some thoughts on
> rewording and fixing various parts of the text would be nice.

The interdiff isn't too helpful to me here.  I'd prefer to review a
complete patch against master.

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Wed, 14 Aug 2024 02:24:01 GMT) Full text and rfc822 format available.

Message #65 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Wed, 14 Aug 2024 04:21:32 +0200
[Message part 1 (text/plain, inline)]
> You're not keen on either of my other suggestions, right?
>
>     cl-once-only-many, cl-once-only-these

No, I am really *really* not that enthusiastic about either of those
names.  `*-these' is completely out of the question, and `*-many'
is... fine, but IMO sounds worse than `*-multiple'.

> I guess I am hung up on how -multiple- is already used in CL names,
> but it comes *before* the things that are multiple.  But I believe you
> don't like cl-multiple-once-only.

`multiple' seems to be used exclusively in `cl-multiple-value-*' names,
so there is some possibility that this might maybe be confused as a part
of that suite, but I don't think it's a particularly significant one.

> The interdiff isn't too helpful to me here.  I'd prefer to review a
> complete patch against master.

Oops, sorry for the bad patch, I've attached the full diff.

[cl-texi-second-draft.patch (text/x-patch, inline)]
diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi
index 113029700ec..de9f0565d03 100644
--- a/doc/misc/cl.texi
+++ b/doc/misc/cl.texi
@@ -999,7 +999,7 @@ Control Structure
 * Iteration::              @code{cl-do}, @code{cl-dotimes}, @code{cl-dolist}, @code{cl-do-symbols}.
 * Loop Facility::          The Common Lisp @code{loop} macro.
 * Multiple Values::        @code{cl-values}, @code{cl-multiple-value-bind}, etc.
-* Macro-Writing Macros::   @code{cl-with-gensyms}, @code{cl-once-only}.
+* Macro-Writing Macros::   @code{cl-with-gensyms}, @code{cl-once-only}, @code{cl-once-only*}.
 @end menu
 
 @node Assignment
@@ -2683,6 +2683,73 @@ Macro-Writing Macros
 @end example
 @end defmac
 
+@defmac cl-once-only* (variable forms) body
+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.
+
+Each element of @var{variable} may be used to refer to the result of
+evaluating the corresponding form in @var{forms} within @var{body}.
+@code{cl-once-only*} binds @var{variable} to a list of fresh uninterned
+symbols.  @code{cl-once-only*} furthermore wraps the final expansion
+such that each form is evaluated in order and its result is bound to the
+corresponding symbol.
+
+Like @code{cl-once-only}, the first argument can be a symbol @var{variable}, which
+is equivalent to writing @code{(variable variable)}.
+
+Consider the following macro:
+
+@example
+(defmacro my-list (vals &rest forms)
+  (let ((val-results (mapcar (lambda (_) (gensym)) vals)))
+    `(let* ,(cl-mapcar #'list val-results vals)
+       (list ,(cl-first val-results)
+             ,(cl-second val-results)
+             ,@@val-results
+             (progn ,@@forms)))))
+@end example
+
+In a call like @code{(my-list ((pop foo) (cl-incf bar) ...) ...)} the
+@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*}:
+
+@example
+(defmacro my-list (vals &rest forms)
+  (cl-once-only* vals
+    `(list ,(cl-first vals)
+           ,(cl-second vals)
+           ,@@vals
+           (progn ,@@forms))))
+@end example
+
+which preserves the fact the @var{vals} is a list and removes
+boiler-plate code for generating and assigning temporary variables.
+@end defmac
+
 @node Macros
 @chapter Macros
 
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 2e501005bf7..adb9cb29104 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -2544,6 +2544,54 @@ cl-once-only
                           collect `(,(car name) ,gensym))
              ,@body)))))
 
+(defmacro cl-once-only* (listvar &rest body)
+  "Generate code to evaluate the list of FORMS just once in BODY.
+
+This is a macro to be used while defining other macros.  FORMS is
+evaluated once during macroexpansion to obtain the list of forms.  In
+the fully expanded code those forms will be evaluated once before BODY
+and their results will be bound to fresh uninterned variables, one for
+each form.
+
+Within the macro VARIABLE is a list of these symbols in order, such that
+each form in FORMS can be accessed by using the corresponding element in
+VARIABLE.
+
+The common case of `(cl-once-only* (VARIABLE VARIABLE) ...)' can be
+written shortly as `(cl-once-only* VARIABLE ...)'.
+
+For example, the following macro:
+
+  (defmacro my-list (head &rest args)
+    (cl-once-only* args
+      \\=`(list (,head ,@args) ,@args)))
+
+when called like
+
+  (let ((x \\='(1 5 4)))
+    (my-list + (pop x) (1+ (pop x)) (1- (pop x))))
+
+will expand into
+
+  (let ((x \\='(1 5 4)))
+    (let* ((arg1 (pop x)) (arg2 (1+ (pop x))) (arg3 (1- (pop x))))
+      (list (+ arg1 arg2 arg3) arg1 arg2 arg3)))
+
+and the arguments will be evaluated only once and in order.
+
+\(fn (VARIABLE FORMS) &body BODY)"
+  (declare (debug ([&or symbolp (symbolp form)] body)) (indent 1))
+  (let* ((variable (if (symbolp listvar) listvar (nth 0 listvar)))
+         (forms    (if (symbolp listvar) listvar (nth 1 listvar)))
+         (results* (gensym (symbol-name variable))))
+    (cl-once-only (forms)
+      `(let ((,results*
+              (cl-loop for i from 1 to (length ,forms) collect
+                       (make-symbol (format "%s$%d" ',(symbol-name variable) i)))))
+         `(let* ,(cl-mapcar #'list ,results* ,forms)
+            ,(let ((,variable ,results*))
+               ,@body))))))
+
 ;;; Multiple values.
 
 ;;;###autoload

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Wed, 14 Aug 2024 06:12:02 GMT) Full text and rfc822 format available.

Message #68 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org, spwhitton <at> spwhitton.name
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Wed, 14 Aug 2024 09:09:04 +0300
> Cc: 72344 <at> debbugs.gnu.org
> From: Thuna <thuna.cing <at> gmail.com>
> 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 <at> dots{}"? or maybe "form <at> 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 [...]





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Wed, 14 Aug 2024 09:48:01 GMT) Full text and rfc822 format available.

Message #71 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Wed, 14 Aug 2024 17:47:05 +0800
Hello,

On Wed 14 Aug 2024 at 04:21am +02, Thuna wrote:

>> You're not keen on either of my other suggestions, right?
>>
>>     cl-once-only-many, cl-once-only-these
>
> No, I am really *really* not that enthusiastic about either of those
> names.  `*-these' is completely out of the question, and `*-many'
> is... fine, but IMO sounds worse than `*-multiple'.

Okay, then let's go with cl-once-only-multiple.

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Wed, 14 Aug 2024 14:17:02 GMT) Full text and rfc822 format available.

Message #74 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 72344 <at> debbugs.gnu.org, spwhitton <at> spwhitton.name
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Wed, 14 Aug 2024 16:14:12 +0200
>> +@defmac cl-once-only* (variable forms) body
>                                    ^^^^^
> Shouldn't this be "forms <at> dots{}"? or maybe "form <at> 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}, ".




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Wed, 14 Aug 2024 14:31:01 GMT) Full text and rfc822 format available.

Message #77 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org, spwhitton <at> spwhitton.name
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Wed, 14 Aug 2024 17:29:44 +0300
> From: Thuna <thuna.cing <at> gmail.com>
> Cc: spwhitton <at> spwhitton.name, 72344 <at> debbugs.gnu.org
> Date: Wed, 14 Aug 2024 16:14:12 +0200
> 
> >> +@defmac cl-once-only* (variable forms) body
> >                                    ^^^^^
> > Shouldn't this be "forms <at> dots{}"? or maybe "form <at> 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.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Thu, 15 Aug 2024 01:08:01 GMT) Full text and rfc822 format available.

Message #80 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 72344 <at> debbugs.gnu.org, spwhitton <at> spwhitton.name
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Thu, 15 Aug 2024 03:05:42 +0200
>> >> +@defmac cl-once-only* (variable forms) body
>> >                                   ^^^^^
>> > Shouldn't this be "forms <at> dots{}"? or maybe "form <at> 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.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Thu, 15 Aug 2024 06:30:02 GMT) Full text and rfc822 format available.

Message #83 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org, spwhitton <at> spwhitton.name
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Thu, 15 Aug 2024 09:28:35 +0300
> From: Thuna <thuna.cing <at> gmail.com>
> Cc: spwhitton <at> spwhitton.name, 72344 <at> debbugs.gnu.org
> Date: Thu, 15 Aug 2024 03:05:42 +0200
> 
> >> >> +@defmac cl-once-only* (variable forms) body
> >> >                                   ^^^^^
> >> > Shouldn't this be "forms <at> dots{}"? or maybe "form <at> 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.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Thu, 15 Aug 2024 12:40:02 GMT) Full text and rfc822 format available.

Message #86 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Thu, 15 Aug 2024 20:38:23 +0800
Hello Thuna,

Can you respin your patch to mention cl-once-only-multiple now we've
agreed on that, please?

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Thu, 15 Aug 2024 15:05:02 GMT) Full text and rfc822 format available.

Message #89 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: 72344 <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Thu, 15 Aug 2024 17:02:27 +0200
> Can you respin your patch to mention cl-once-only-multiple now we've
> agreed on that, please?

Yep, will do, sorry about that.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Thu, 15 Aug 2024 15:17:02 GMT) Full text and rfc822 format available.

Message #92 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Thuna <thuna.cing <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 72344 <at> debbugs.gnu.org, spwhitton <at> spwhitton.name
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Thu, 15 Aug 2024 17:15:10 +0200
> 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)?

No, no, it's rather that the evaluation is a given, the same way it is
in, e.g. if-let (and also cl-once-only, where the evaluation of form(1)
to obtain form(2) during 2 isn't explicitly mentioned).

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

Regardless, if even you are confused, then something has certainly gone
wrong with my explanation, so I'll try to get another draft going.

In the meanwhile, what do you think about the docstring?  It seems to me
that it mentions what happens to FORMS more accurately, but if there are
problems with it then I'll also need to look into changing that.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Thu, 15 Aug 2024 16:23:02 GMT) Full text and rfc822 format available.

Message #95 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Thuna <thuna.cing <at> gmail.com>
Cc: 72344 <at> debbugs.gnu.org, spwhitton <at> spwhitton.name
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Thu, 15 Aug 2024 19:20:01 +0300
> From: Thuna <thuna.cing <at> gmail.com>
> Cc: spwhitton <at> spwhitton.name, 72344 <at> debbugs.gnu.org
> Date: Thu, 15 Aug 2024 17:15:10 +0200
> 
> In the meanwhile, what do you think about the docstring?  It seems to me
> that it mentions what happens to FORMS more accurately, but if there are
> problems with it then I'll also need to look into changing that.

It still says something similar:

  +                                                         FORMS is
  +evaluated once during macroexpansion to obtain the list of forms.  In
  +the fully expanded code those forms will be evaluated once before BODY
  +and their results will be bound to fresh uninterned variables, one for
  +each form.

So I think we need to fix that as well.  I hope once we have the text
for the manual ready, it will be easier to figure out how to say the
same in the doc string.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#72344; Package emacs. (Mon, 19 Aug 2024 16:56:03 GMT) Full text and rfc822 format available.

Message #98 received at 72344 <at> debbugs.gnu.org (full text, mbox):

From: Richard Stallman <rms <at> gnu.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 72344 <at> debbugs.gnu.org, thuna.cing <at> gmail.com, spwhitton <at> spwhitton.name
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Mon, 19 Aug 2024 12:54:46 -0400
[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

I still maintain that we should integrate this fully accept this
construct into Emacs, by deleting `cl-' from its name.
-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)






Severity set to 'wishlist' from 'normal' Request was from Stefan Kangas <stefankangas <at> gmail.com> to control <at> debbugs.gnu.org. (Thu, 13 Feb 2025 07:00:03 GMT) Full text and rfc822 format available.

Reply sent to Sean Whitton <spwhitton <at> spwhitton.name>:
You have taken responsibility. (Tue, 08 Apr 2025 05:11:01 GMT) Full text and rfc822 format available.

Notification sent to Thuna <thuna.cing <at> gmail.com>:
bug acknowledged by developer. (Tue, 08 Apr 2025 05:11:01 GMT) Full text and rfc822 format available.

Message #105 received at 72344-close <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Thuna <thuna.cing <at> gmail.com>, 72344-close <at> debbugs.gnu.org
Subject: Re: bug#72344: [PATCH] Add a version of cl-once-only which handles
 lists of forms
Date: Tue, 08 Apr 2025 13:10:05 +0800
Hello,

On Sun 28 Jul 2024 at 11:17pm +02, Thuna wrote:

> (My motivation for this is to use this macro in another patch which I
> didn't want to make longer with out-of-scope additions.  If this is
> considered not worth polluting the `cl-' namespace over I can just write
> the forms by hand so it's fine either way.)

This discussion hasn't been active for almost a year now.
The proposed cl-once-only-multiple is indeed fairly idiosyncratic and
unlikely to see much use, so I think we should probably just close this
request for now.  Going ahead and doing that.

-- 
Sean Whitton




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 06 May 2025 11:24:22 GMT) Full text and rfc822 format available.

This bug report was last modified 55 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.