emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 5e3fde0: Improve docstring for macroexp-let2


From: Paul Eggert
Subject: [Emacs-diffs] master 5e3fde0: Improve docstring for macroexp-let2
Date: Sat, 27 Jun 2015 15:35:17 +0000

branch: master
commit 5e3fde03b45877d3e30f859a14c10043e637aa63
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Improve docstring for macroexp-let2
    
    * lisp/emacs-lisp/macroexp.el (macroexp-let2):
    Improve as per suggestion by RMS in:
    http://lists.gnu.org/archive/html/emacs-devel/2015-06/msg00621.html
    Also, rename args to match new doc string.
---
 lisp/emacs-lisp/macroexp.el |   45 ++++++++++++++++++++++++++++++++----------
 1 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index e9af3b0..57cbec5 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -341,21 +341,44 @@ definitions to shadow the loaded ones for use in file 
byte-compilation."
    ((memq (car-safe then) '(if cond)) (macroexp-if `(not ,test) else then))
    (t `(if ,test ,then ,else))))
 
-(defmacro macroexp-let2 (test var exp &rest exps)
-  "Bind VAR to a copyable expression that returns the value of EXP.
-This is like \\=`(let ((v ,EXP)) ,EXPS) except that `v' is a new generated
-symbol which EXPS can find in VAR.
-TEST should be the name of a predicate on EXP checking whether the `let' can
-be skipped; if nil, as is usual, `macroexp-const-p' is used."
+(defmacro macroexp-let2 (test sym exp &rest body)
+  "Evaluate BODY with SYM bound to an expression for EXP's value.
+The intended usage is that BODY generates an expression that
+will refer to EXP's value multiple times, but will evaluate
+EXP only once.  As BODY generates that expression, it should
+use SYM to stand for the value of EXP.
+
+If EXP is a simple, safe expression, then SYM's value is EXP itself.
+Otherwise, SYM's value is a symbol which holds the value produced by
+evaluating EXP.  The return value incorporates the value of BODY, plus
+additional code to evaluate EXP once and save the result so SYM can
+refer to it.
+
+If BODY consists of multiple forms, they are all evaluated
+but only the last one's value matters.
+
+TEST is a predicate to determine whether EXP qualifies as simple and
+safe; if TEST is nil, only constant expressions qualify.
+
+Example:
+ (macroexp-let2 nil foo EXP
+   \\=`(* ,foo ,foo))
+generates an expression that evaluates EXP once,
+then returns the square of that value.
+You could do this with
+  (let ((foovar EXP))
+    (* foovar foovar))
+but using `macroexp-let2' produces more efficient code in
+cases where EXP is a constant."
   (declare (indent 3) (debug (sexp sexp form body)))
   (let ((bodysym (make-symbol "body"))
         (expsym (make-symbol "exp")))
     `(let* ((,expsym ,exp)
-            (,var (if (funcall #',(or test #'macroexp-const-p) ,expsym)
-                      ,expsym (make-symbol ,(symbol-name var))))
-            (,bodysym ,(macroexp-progn exps)))
-       (if (eq ,var ,expsym) ,bodysym
-         (macroexp-let* (list (list ,var ,expsym))
+            (,sym (if (funcall #',(or test #'macroexp-const-p) ,expsym)
+                      ,expsym (make-symbol ,(symbol-name sym))))
+            (,bodysym ,(macroexp-progn body)))
+       (if (eq ,sym ,expsym) ,bodysym
+         (macroexp-let* (list (list ,sym ,expsym))
                         ,bodysym)))))
 
 (defmacro macroexp-let2* (test bindings &rest body)



reply via email to

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