emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Adding with-gensyms and once-only to subr-x


From: Stefan Monnier
Subject: Re: [PATCH] Adding with-gensyms and once-only to subr-x
Date: Mon, 11 Apr 2022 13:26:12 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)

>>> Lately I have been finding myself wanting with-gensyms and once-only,
>>> two classic macro-writing macros, available in core Elisp.  (There is
>>> already org-with-gensyms, but it's not in the least bit Org-specific.)
>> I think `once-only` is what we (well, I) called `macroexp-let2`.
> Ah, thank you for the pointer.
>
> (macroexp-let2* nil ((foo foo) (bar bar)) FORMS)
>
> is quite a bit more verbose than (once-only (foo bar) FORMS), however.
> So I would be inclined to keep once-only, though reimplemented in terms
> of macroexp-let2*.  Does that sound reasonable?

How 'bout making `macroexp-let2*` accept the shorter form as in the
patch below?

I'm not in love with the name `macroexp-let2*` but I find the name
`once-only` to lack context.  So we could consider renaming, but I'd
favor making it live in `macroexp.el` (and come with a `macroexp-`
prefix).  It could be called `macroexp-once-only` or
`macroexp-eval-now`, or we could go crazy with names like
`macroexp-copyableize`.


        Stefan


diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 1420655f1e9..4783e55e057 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -636,12 +636,20 @@ macroexp-let2
 (defmacro macroexp-let2* (test bindings &rest body)
   "Multiple binding version of `macroexp-let2'.
 
-BINDINGS is a list of elements of the form (SYM EXP).  Each EXP
-can refer to symbols specified earlier in the binding list."
+BINDINGS is a list of elements of the form (SYM EXP) or just SYM,
+which then stands for (SYM SYM).
+Each EXP can refer to symbols specified earlier in the binding list.
+
+TEST has to be a symbol, and if it is nil it can be omitted."
   (declare (indent 2) (debug (sexp (&rest (sexp form)) body)))
+  (when (consp test) ;; `test' was omitted.
+    (push bindings body)
+    (setq bindings test)
+    (setq test nil))
   (pcase-exhaustive bindings
     ('nil (macroexp-progn body))
-    (`((,var ,exp) . ,tl)
+    (`(,(or `(,var ,exp) (and (pred symbolp) ,var (let ,exp var)))
+       . ,tl)
      `(macroexp-let2 ,test ,var ,exp
         (macroexp-let2* ,test ,tl ,@body)))))
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]