summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2015-06-27 08:34:44 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2015-06-27 08:35:13 -0700
commit5e3fde03b45877d3e30f859a14c10043e637aa63 (patch)
tree5eec042dddf9bde298a11dfad967e7662e004c56 /lisp/emacs-lisp
parent7baae811651d73b3e89c832a5c15ff5b40c82635 (diff)
downloademacs-5e3fde03b45877d3e30f859a14c10043e637aa63.tar.gz
emacs-5e3fde03b45877d3e30f859a14c10043e637aa63.tar.bz2
emacs-5e3fde03b45877d3e30f859a14c10043e637aa63.zip
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.
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/macroexp.el45
1 files changed, 34 insertions, 11 deletions
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index e9af3b08997..57cbec580b0 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)