all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
@ 2024-07-28 21:17 Thuna
  2024-07-29  0:39 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-07-29  7:09 ` Sean Whitton
  0 siblings, 2 replies; 34+ messages in thread
From: Thuna @ 2024-07-28 21:17 UTC (permalink / raw)
  To: 72344

[-- Attachment #1: Type: text/plain, Size: 777 bytes --]

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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-a-version-of-cl-once-only-which-handles-lists-of.patch --]
[-- Type: text/x-patch, Size: 2112 bytes --]

From e8af4374454965d541ad3b8062e6793217d4e86f Mon Sep 17 00:00:00 2001
From: Thuna <thuna.cing@gmail.com>
Date: Sun, 28 Jul 2024 22:26:41 +0200
Subject: [PATCH] Add a version of cl-once-only which handles lists of forms

* lisp/emacs-lisp/cl-macs.el (cl-once-only*): Define macro.
---
 lisp/emacs-lisp/cl-macs.el | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 2e501005bf7..70d66b3a250 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -2544,6 +2544,43 @@ cl-once-only
                           collect `(,(car name) ,gensym))
              ,@body)))))
 
+(defmacro cl-once-only* (listvar &rest body)
+  "Generate code to evaluate the list of forms LISTVAR just once in BODY.
+
+This is a macro to be used while defining other macros.  LISTVAR should
+be a variable which holds a list of forms, such as ARGS in a function
+call of the form \\=`(,head ,@args).  Within BODY, the variable LISTVAR
+will be bound to a list of uninterned symbols of the same length, all of
+which are variables in the final macroexpansion which are bound to the
+result of evaluating the corresponding form.
+
+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."
+  (declare (debug (arg body)) (indent 1))
+  (let ((args (gensym (symbol-name listvar))))
+    `(let ((,args
+            (cl-loop for i from 1 to (length ,listvar) collect
+                     (make-symbol (format "%s$%d" ',(symbol-name args) i)))))
+       `(let* ,(cl-mapcar #'list ,args ,listvar)
+          ,(let ((,listvar ,args))
+             ,@body)))))
+
 ;;; Multiple values.
 
 ;;;###autoload
-- 
2.44.2


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-07-28 21:17 bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms Thuna
@ 2024-07-29  0:39 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-07-29 19:30   ` Thuna
  2024-07-29  7:09 ` Sean Whitton
  1 sibling, 1 reply; 34+ messages in thread
From: Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-07-29  0:39 UTC (permalink / raw)
  To: Thuna, 72344@debbugs.gnu.org

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








^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-07-28 21:17 bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms Thuna
  2024-07-29  0:39 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-07-29  7:09 ` Sean Whitton
  2024-07-29 19:54   ` Thuna
  1 sibling, 1 reply; 34+ messages in thread
From: Sean Whitton @ 2024-07-29  7:09 UTC (permalink / raw)
  To: Thuna; +Cc: 72344

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-07-29  0:39 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-07-29 19:30   ` Thuna
  2024-07-29 19:54     ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 34+ messages in thread
From: Thuna @ 2024-07-29 19:30 UTC (permalink / raw)
  To: Drew Adams; +Cc: 72344


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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-07-29 19:30   ` Thuna
@ 2024-07-29 19:54     ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 34+ messages in thread
From: Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-07-29 19:54 UTC (permalink / raw)
  To: Thuna; +Cc: 72344@debbugs.gnu.org

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-07-29  7:09 ` Sean Whitton
@ 2024-07-29 19:54   ` Thuna
  2024-08-03  2:51     ` Sean Whitton
  0 siblings, 1 reply; 34+ messages in thread
From: Thuna @ 2024-07-29 19:54 UTC (permalink / raw)
  To: Sean Whitton; +Cc: 72344


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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-07-29 19:54   ` Thuna
@ 2024-08-03  2:51     ` Sean Whitton
  2024-08-03 22:40       ` Thuna
  0 siblings, 1 reply; 34+ messages in thread
From: Sean Whitton @ 2024-08-03  2:51 UTC (permalink / raw)
  To: Thuna; +Cc: 72344

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-03  2:51     ` Sean Whitton
@ 2024-08-03 22:40       ` Thuna
  2024-08-06  1:41         ` Sean Whitton
  0 siblings, 1 reply; 34+ messages in thread
From: Thuna @ 2024-08-03 22:40 UTC (permalink / raw)
  To: Sean Whitton; +Cc: 72344

[-- Attachment #1: Type: text/plain, Size: 1641 bytes --]

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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-a-version-of-cl-once-only-which-works-on-a-list-.patch --]
[-- Type: text/x-patch, Size: 5005 bytes --]

From 18f72562f888d0abe56601544b23358429b7afcd Mon Sep 17 00:00:00 2001
From: Thuna <thuna.cing@gmail.com>
Date: Sun, 4 Aug 2024 00:30:44 +0200
Subject: [PATCH] Add a version of cl-once-only which works on a list of forms

---
 doc/misc/cl.texi           | 49 +++++++++++++++++++++++++++++++++++++-
 lisp/emacs-lisp/cl-macs.el | 48 +++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi
index 113029700ec..57e2f3a6c3b 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,53 @@ 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 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.
+
+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 (head &rest args)
+  (cl-once-only ((args `(list ,@@args))
+    `(list (apply #',head ,args)
+           ,args
+           (nth 1 ,args))))
+@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)}.
+
+Consider the alternative using @code{cl-once-only*}:
+
+@example
+(defmacro my-list (head &rest args)
+  (cl-once-only* args
+    `(list (,head ,@@args)
+           (list ,@@args)
+           ,(nth 1 args))))
+@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}.
+@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
-- 
2.44.2


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-03 22:40       ` Thuna
@ 2024-08-06  1:41         ` Sean Whitton
  2024-08-06  1:47           ` Sean Whitton
                             ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: Sean Whitton @ 2024-08-06  1:41 UTC (permalink / raw)
  To: Thuna; +Cc: 72344

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-06  1:41         ` Sean Whitton
@ 2024-08-06  1:47           ` Sean Whitton
  2024-08-09  5:44             ` Sean Whitton
  2024-08-06 12:28           ` Thuna
  2024-08-06 15:52           ` bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2 siblings, 1 reply; 34+ messages in thread
From: Sean Whitton @ 2024-08-06  1:47 UTC (permalink / raw)
  To: Thuna; +Cc: 72344

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-06  1:41         ` Sean Whitton
  2024-08-06  1:47           ` Sean Whitton
@ 2024-08-06 12:28           ` Thuna
  2024-08-06 12:37             ` Sean Whitton
  2024-08-10  2:30             ` why call it `cl-once-only'? Richard Stallman
  2024-08-06 15:52           ` bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2 siblings, 2 replies; 34+ messages in thread
From: Thuna @ 2024-08-06 12:28 UTC (permalink / raw)
  To: Sean Whitton; +Cc: 72344

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-06 12:28           ` Thuna
@ 2024-08-06 12:37             ` Sean Whitton
  2024-08-13 21:17               ` Thuna
  2024-08-10  2:30             ` why call it `cl-once-only'? Richard Stallman
  1 sibling, 1 reply; 34+ messages in thread
From: Sean Whitton @ 2024-08-06 12:37 UTC (permalink / raw)
  To: Thuna; +Cc: 72344

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-06  1:41         ` Sean Whitton
  2024-08-06  1:47           ` Sean Whitton
  2024-08-06 12:28           ` Thuna
@ 2024-08-06 15:52           ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2 siblings, 0 replies; 34+ messages in thread
From: Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-06 15:52 UTC (permalink / raw)
  To: Sean Whitton, Thuna; +Cc: 72344@debbugs.gnu.org

s/cl-/cl--, please.  None of the constructs
mentioned correspond to actual Common Lisp
constructs.






^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-06  1:47           ` Sean Whitton
@ 2024-08-09  5:44             ` Sean Whitton
  0 siblings, 0 replies; 34+ messages in thread
From: Sean Whitton @ 2024-08-09  5:44 UTC (permalink / raw)
  To: Thuna; +Cc: 72344

Hello Thuna,

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

?

-- 
Sean Whitton





^ permalink raw reply	[flat|nested] 34+ messages in thread

* why call it `cl-once-only'?
  2024-08-06 12:28           ` Thuna
  2024-08-06 12:37             ` Sean Whitton
@ 2024-08-10  2:30             ` Richard Stallman
  2024-08-10  3:31               ` Emanuel Berg
  1 sibling, 1 reply; 34+ messages in thread
From: Richard Stallman @ 2024-08-10  2:30 UTC (permalink / raw)
  To: emacs-devel

Why does the construct `cl-once-only' have the prefix `cl'?
There is no `once-only' without the `cl'.

If this construct is worth having for the sake of programs written for
Emacs Lisp, and its definition is going to be present all the time, we
may as well add it with a simpler 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)





^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: why call it `cl-once-only'?
  2024-08-10  2:30             ` why call it `cl-once-only'? Richard Stallman
@ 2024-08-10  3:31               ` Emanuel Berg
  0 siblings, 0 replies; 34+ messages in thread
From: Emanuel Berg @ 2024-08-10  3:31 UTC (permalink / raw)
  To: emacs-devel

Richard Stallman wrote:

> Why does the construct `cl-once-only' have the prefix `cl'?
> There is no `once-only' without the `cl'.

There is a lot of such stuff.

Including pretty ordinary stuff, for example no incf, decf,
pushnew or labels, but `cl-incf', `cl-decf', `cl-pushnew', and
`cl-labels'.

So I think "cl-" prefix denotes the package and library first,
and only second it is also used to disambiguate with old
school Elisp whenever needed. Since that won't have it
for sure.

> If this construct is worth having for the sake of programs
> written for Emacs Lisp, and its definition is going to be
> present all the time, we may as well add it with
> a simpler name.

It seems to be used 7 times in 2 different files in
core Emacs.

That's not so bad! I have a lot of stuff used 0 times in 0
files, hehe.

-- 
underground experts united
https://dataswamp.org/~incal




^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-06 12:37             ` Sean Whitton
@ 2024-08-13 21:17               ` Thuna
  2024-08-13 21:36                 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-14  0:05                 ` Sean Whitton
  0 siblings, 2 replies; 34+ messages in thread
From: Thuna @ 2024-08-13 21:17 UTC (permalink / raw)
  To: Sean Whitton; +Cc: 72344, drew.adams

[-- Attachment #1: Type: text/plain, Size: 1136 bytes --]

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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: cl-texi-second-draft.patch --]
[-- Type: text/x-patch, Size: 3983 bytes --]

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-13 21:17               ` Thuna
@ 2024-08-13 21:36                 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-13 22:18                   ` Thuna
  2024-08-14  0:05                 ` Sean Whitton
  1 sibling, 1 reply; 34+ messages in thread
From: Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-13 21:36 UTC (permalink / raw)
  To: Thuna, Sean Whitton; +Cc: 72344@debbugs.gnu.org

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-13 21:36                 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-13 22:18                   ` Thuna
  2024-08-13 22:57                     ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-14  0:01                     ` Sean Whitton
  0 siblings, 2 replies; 34+ messages in thread
From: Thuna @ 2024-08-13 22:18 UTC (permalink / raw)
  To: Drew Adams; +Cc: 72344, Sean Whitton

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-13 22:18                   ` Thuna
@ 2024-08-13 22:57                     ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-14  0:01                     ` Sean Whitton
  1 sibling, 0 replies; 34+ messages in thread
From: Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-13 22:57 UTC (permalink / raw)
  To: Thuna; +Cc: 72344@debbugs.gnu.org, Sean Whitton

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-13 22:18                   ` Thuna
  2024-08-13 22:57                     ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-14  0:01                     ` Sean Whitton
  1 sibling, 0 replies; 34+ messages in thread
From: Sean Whitton @ 2024-08-14  0:01 UTC (permalink / raw)
  To: Thuna; +Cc: 72344, Drew Adams

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-13 21:17               ` Thuna
  2024-08-13 21:36                 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-14  0:05                 ` Sean Whitton
  2024-08-14  2:21                   ` Thuna
  1 sibling, 1 reply; 34+ messages in thread
From: Sean Whitton @ 2024-08-14  0:05 UTC (permalink / raw)
  To: Thuna; +Cc: 72344, drew.adams

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-14  0:05                 ` Sean Whitton
@ 2024-08-14  2:21                   ` Thuna
  2024-08-14  6:09                     ` Eli Zaretskii
  2024-08-14  9:47                     ` Sean Whitton
  0 siblings, 2 replies; 34+ messages in thread
From: Thuna @ 2024-08-14  2:21 UTC (permalink / raw)
  To: Sean Whitton; +Cc: 72344

[-- Attachment #1: Type: text/plain, Size: 856 bytes --]

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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: cl-texi-second-draft.patch --]
[-- Type: text/x-patch, Size: 5535 bytes --]

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-14  2:21                   ` Thuna
@ 2024-08-14  6:09                     ` Eli Zaretskii
  2024-08-14 14:14                       ` Thuna
  2024-08-14  9:47                     ` Sean Whitton
  1 sibling, 1 reply; 34+ messages in thread
From: Eli Zaretskii @ 2024-08-14  6:09 UTC (permalink / raw)
  To: Thuna; +Cc: 72344, spwhitton

> Cc: 72344@debbugs.gnu.org
> From: Thuna <thuna.cing@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@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 [...]






^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-14  2:21                   ` Thuna
  2024-08-14  6:09                     ` Eli Zaretskii
@ 2024-08-14  9:47                     ` Sean Whitton
  1 sibling, 0 replies; 34+ messages in thread
From: Sean Whitton @ 2024-08-14  9:47 UTC (permalink / raw)
  To: Thuna; +Cc: 72344

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-14  6:09                     ` Eli Zaretskii
@ 2024-08-14 14:14                       ` Thuna
  2024-08-14 14:29                         ` Eli Zaretskii
  2024-08-15 12:38                         ` Sean Whitton
  0 siblings, 2 replies; 34+ messages in thread
From: Thuna @ 2024-08-14 14:14 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 72344, spwhitton

>> +@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}, ".





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-14 14:14                       ` Thuna
@ 2024-08-14 14:29                         ` Eli Zaretskii
  2024-08-15  1:05                           ` Thuna
  2024-08-15 12:38                         ` Sean Whitton
  1 sibling, 1 reply; 34+ messages in thread
From: Eli Zaretskii @ 2024-08-14 14:29 UTC (permalink / raw)
  To: Thuna; +Cc: 72344, spwhitton

> From: Thuna <thuna.cing@gmail.com>
> Cc: spwhitton@spwhitton.name, 72344@debbugs.gnu.org
> 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?

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.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-14 14:29                         ` Eli Zaretskii
@ 2024-08-15  1:05                           ` Thuna
  2024-08-15  6:28                             ` Eli Zaretskii
  0 siblings, 1 reply; 34+ messages in thread
From: Thuna @ 2024-08-15  1:05 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 72344, spwhitton

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-15  1:05                           ` Thuna
@ 2024-08-15  6:28                             ` Eli Zaretskii
  2024-08-15 15:15                               ` Thuna
  0 siblings, 1 reply; 34+ messages in thread
From: Eli Zaretskii @ 2024-08-15  6:28 UTC (permalink / raw)
  To: Thuna; +Cc: 72344, spwhitton

> From: Thuna <thuna.cing@gmail.com>
> Cc: spwhitton@spwhitton.name, 72344@debbugs.gnu.org
> 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.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-14 14:14                       ` Thuna
  2024-08-14 14:29                         ` Eli Zaretskii
@ 2024-08-15 12:38                         ` Sean Whitton
  2024-08-15 15:02                           ` Thuna
  1 sibling, 1 reply; 34+ messages in thread
From: Sean Whitton @ 2024-08-15 12:38 UTC (permalink / raw)
  To: Thuna; +Cc: 72344, Eli Zaretskii

Hello Thuna,

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

-- 
Sean Whitton





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-15 12:38                         ` Sean Whitton
@ 2024-08-15 15:02                           ` Thuna
  0 siblings, 0 replies; 34+ messages in thread
From: Thuna @ 2024-08-15 15:02 UTC (permalink / raw)
  To: Sean Whitton; +Cc: 72344

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

Yep, will do, sorry about that.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-15  6:28                             ` Eli Zaretskii
@ 2024-08-15 15:15                               ` Thuna
  2024-08-15 16:20                                 ` Eli Zaretskii
  0 siblings, 1 reply; 34+ messages in thread
From: Thuna @ 2024-08-15 15:15 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 72344, spwhitton

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





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-15 15:15                               ` Thuna
@ 2024-08-15 16:20                                 ` Eli Zaretskii
  2024-08-19 16:54                                   ` Richard Stallman
  0 siblings, 1 reply; 34+ messages in thread
From: Eli Zaretskii @ 2024-08-15 16:20 UTC (permalink / raw)
  To: Thuna; +Cc: 72344, spwhitton

> From: Thuna <thuna.cing@gmail.com>
> Cc: spwhitton@spwhitton.name, 72344@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.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms
  2024-08-15 16:20                                 ` Eli Zaretskii
@ 2024-08-19 16:54                                   ` Richard Stallman
  0 siblings, 0 replies; 34+ messages in thread
From: Richard Stallman @ 2024-08-19 16:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 72344, thuna.cing, spwhitton

[[[ 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)







^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2024-08-19 16:54 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-28 21:17 bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms Thuna
2024-07-29  0:39 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-07-29 19:30   ` Thuna
2024-07-29 19:54     ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-07-29  7:09 ` Sean Whitton
2024-07-29 19:54   ` Thuna
2024-08-03  2:51     ` Sean Whitton
2024-08-03 22:40       ` Thuna
2024-08-06  1:41         ` Sean Whitton
2024-08-06  1:47           ` Sean Whitton
2024-08-09  5:44             ` Sean Whitton
2024-08-06 12:28           ` Thuna
2024-08-06 12:37             ` Sean Whitton
2024-08-13 21:17               ` Thuna
2024-08-13 21:36                 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-13 22:18                   ` Thuna
2024-08-13 22:57                     ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-14  0:01                     ` Sean Whitton
2024-08-14  0:05                 ` Sean Whitton
2024-08-14  2:21                   ` Thuna
2024-08-14  6:09                     ` Eli Zaretskii
2024-08-14 14:14                       ` Thuna
2024-08-14 14:29                         ` Eli Zaretskii
2024-08-15  1:05                           ` Thuna
2024-08-15  6:28                             ` Eli Zaretskii
2024-08-15 15:15                               ` Thuna
2024-08-15 16:20                                 ` Eli Zaretskii
2024-08-19 16:54                                   ` Richard Stallman
2024-08-15 12:38                         ` Sean Whitton
2024-08-15 15:02                           ` Thuna
2024-08-14  9:47                     ` Sean Whitton
2024-08-10  2:30             ` why call it `cl-once-only'? Richard Stallman
2024-08-10  3:31               ` Emanuel Berg
2024-08-06 15:52           ` bug#72344: [PATCH] Add a version of cl-once-only which handles lists of forms Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.