]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve docstring for macroexp-let2
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 27 Jun 2015 15:34:44 +0000 (08:34 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 27 Jun 2015 15:35:13 +0000 (08:35 -0700)
* 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

index e9af3b08997a4fe0fb44dd314f378a8001098aeb..57cbec580b0deecd4920d119eceed87322957d1c 100644 (file)
@@ -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)