summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/advice.el3
-rw-r--r--lisp/emacs-lisp/cl-extra.el7
-rw-r--r--lisp/emacs-lisp/cl-lib.el7
-rw-r--r--lisp/emacs-lisp/cl-macs.el7
-rw-r--r--lisp/emacs-lisp/cl.el54
-rw-r--r--lisp/emacs-lisp/gv.el17
6 files changed, 66 insertions, 29 deletions
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index 42c25a4613d..8239522c0f8 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -1709,7 +1709,8 @@
;; During a normal load this is a noop:
(require 'advice-preload "advice.el")
(require 'macroexp)
-(eval-when-compile (require 'cl-lib))
+;; At run-time also, since ad-do-advised-functions returns code that uses it.
+(require 'cl-lib)
;; @@ Variable definitions:
;; ========================
diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index a57de344cf3..7c25972835b 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -131,7 +131,7 @@ TYPE is the sequence type to return.
;;;###autoload
(defun cl-maplist (cl-func cl-list &rest cl-rest)
"Map FUNCTION to each sublist of LIST or LISTs.
-Like `mapcar', except applies to lists and their cdr's rather than to
+Like `cl-mapcar', except applies to lists and their cdr's rather than to
the elements themselves.
\n(fn FUNCTION LIST...)"
(if cl-rest
@@ -170,7 +170,7 @@ the elements themselves.
;;;###autoload
(defun cl-mapcan (cl-func cl-seq &rest cl-rest)
- "Like `mapcar', but nconc's together the values returned by the function.
+ "Like `cl-mapcar', but nconc's together the values returned by the function.
\n(fn FUNCTION SEQUENCE...)"
(apply 'nconc (apply 'cl-mapcar cl-func cl-seq cl-rest)))
@@ -675,6 +675,9 @@ PROPLIST is a list of the sort returned by `symbol-plist'.
;;;###autoload
(defun cl-prettyexpand (form &optional full)
+ "Expand macros in FORM and insert the pretty-printed result.
+Optional argument FULL non-nil means to expand all macros,
+including `cl-block' and `cl-eval-when'."
(message "Expanding...")
(let ((cl--compiling-file full)
(byte-compile-macro-environment nil))
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el
index 034a5c7517e..a9be08b1383 100644
--- a/lisp/emacs-lisp/cl-lib.el
+++ b/lisp/emacs-lisp/cl-lib.el
@@ -251,12 +251,17 @@ one value.
(defvar cl-proclaims-deferred nil)
(defun cl-proclaim (spec)
+ "Record a global declaration specified by SPEC."
(if (fboundp 'cl-do-proclaim) (cl-do-proclaim spec t)
(push spec cl-proclaims-deferred))
nil)
(defmacro cl-declaim (&rest specs)
- (let ((body (mapcar (function (lambda (x) (list 'cl-proclaim (list 'quote x))))
+ "Like `cl-proclaim', but takes any number of unevaluated, unquoted arguments.
+Puts `(cl-eval-when (compile load eval) ...)' around the declarations
+so that they are registered at compile-time as well as run-time."
+ (let ((body (mapcar (function (lambda (x)
+ (list 'cl-proclaim (list 'quote x))))
specs)))
(if (cl--compiling-file) (cl-list* 'cl-eval-when '(compile load eval) body)
(cons 'progn body)))) ; avoid loading cl-macs.el for cl-eval-when
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 8d240774edb..b28f8f7f9e9 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -554,6 +554,7 @@ its argument list allows full Common Lisp conventions."
;;;###autoload
(defmacro cl-destructuring-bind (args expr &rest body)
+ "Bind the variables in ARGS to the result of EXPR and execute BODY."
(declare (indent 2)
(debug (&define cl-macro-list def-form cl-declarations def-body)))
(let* ((cl--bind-lets nil) (cl--bind-forms nil) (cl--bind-inits nil)
@@ -1886,10 +1887,12 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C).
;;;###autoload
(defmacro cl-locally (&rest body)
+ "Equivalent to `progn'."
(declare (debug t))
(cons 'progn body))
;;;###autoload
(defmacro cl-the (_type form)
+ "At present this ignores _TYPE and is simply equivalent to FORM."
(declare (indent 1) (debug (cl-type-spec form)))
form)
@@ -2537,6 +2540,10 @@ and then returning foo."
;;;###autoload
(defun cl-compiler-macroexpand (form)
+ "Like `macroexpand', but for compiler macros.
+Expands FORM repeatedly until no further expansion is possible.
+Returns FORM unchanged if it has no compiler macro, or if it has a
+macro that returns its `&whole' argument."
(while
(let ((func (car-safe form)) (handler nil))
(while (and (symbolp func)
diff --git a/lisp/emacs-lisp/cl.el b/lisp/emacs-lisp/cl.el
index d3ef83961e2..016967bc713 100644
--- a/lisp/emacs-lisp/cl.el
+++ b/lisp/emacs-lisp/cl.el
@@ -547,13 +547,15 @@ deprecated usage of `symbol-function' in place forms)." ; bug#12760
(defmacro define-setf-expander (name arglist &rest body)
"Define a `setf' method.
-This method shows how to handle `setf's to places of the form (NAME ARGS...).
-The argument forms ARGS are bound according to ARGLIST, as if NAME were
-going to be expanded as a macro, then the BODY forms are executed and must
-return a list of five elements: a temporary-variables list, a value-forms
-list, a store-variables list (of length one), a store-form, and an access-
-form. See `gv-define-expander', `gv-define-setter', and `gv-define-expander'
-for a better and simpler ways to define setf-methods."
+This method shows how to handle `setf's to places of the form
+\(NAME ARGS...). The argument forms ARGS are bound according to
+ARGLIST, as if NAME were going to be expanded as a macro, then
+the BODY forms are executed and must return a list of five elements:
+a temporary-variables list, a value-forms list, a store-variables list
+\(of length one), a store-form, and an access- form.
+
+See `gv-define-expander', and `gv-define-setter' for better and
+simpler ways to define setf-methods."
(declare (debug
(&define name cl-lambda-list cl-declarations-or-string def-body)))
`(progn
@@ -566,23 +568,31 @@ for a better and simpler ways to define setf-methods."
(defmacro defsetf (name arg1 &rest args)
"Define a `setf' method.
-This macro is an easy-to-use substitute for `define-setf-expander' that works
-well for simple place forms. In the simple `defsetf' form, `setf's of
-the form (setf (NAME ARGS...) VAL) are transformed to function or macro
-calls of the form (FUNC ARGS... VAL). Example:
+This macro is an easy-to-use substitute for `define-setf-expander'
+that works well for simple place forms.
+
+In the simple `defsetf' form, `setf's of the form (setf (NAME
+ARGS...) VAL) are transformed to function or macro calls of the
+form (FUNC ARGS... VAL). For example:
(defsetf aref aset)
+You can replace this form with `gv-define-simple-setter'.
+
Alternate form: (defsetf NAME ARGLIST (STORE) BODY...).
-Here, the above `setf' call is expanded by binding the argument forms ARGS
-according to ARGLIST, binding the value form VAL to STORE, then executing
-BODY, which must return a Lisp form that does the necessary `setf' operation.
-Actually, ARGLIST and STORE may be bound to temporary variables which are
-introduced automatically to preserve proper execution order of the arguments.
-Example:
+
+Here, the above `setf' call is expanded by binding the argument
+forms ARGS according to ARGLIST, binding the value form VAL to
+STORE, then executing BODY, which must return a Lisp form that
+does the necessary `setf' operation. Actually, ARGLIST and STORE
+may be bound to temporary variables which are introduced
+automatically to preserve proper execution order of the arguments.
+For example:
(defsetf nth (n x) (v) `(setcar (nthcdr ,n ,x) ,v))
+You can replace this form with `gv-define-setter'.
+
\(fn NAME [FUNC | ARGLIST (STORE) BODY...])"
(declare (debug
(&define name
@@ -597,7 +607,7 @@ Example:
(cl-function
(lambda (,@(car args) ,@arg1) ,@(cdr args)))
do args)))
- `(gv-define-simple-setter ,name ,arg1)))
+ `(gv-define-simple-setter ,name ,arg1 ,(car args))))
;; FIXME: CL used to provide a setf method for `apply', but I haven't been able
;; to find a case where it worked. The code below tries to handle it as well.
@@ -639,8 +649,12 @@ Example:
(defmacro define-modify-macro (name arglist func &optional doc)
"Define a `setf'-like modify macro.
-If NAME is called, it combines its PLACE argument with the other arguments
-from ARGLIST using FUNC: (define-modify-macro incf (&optional (n 1)) +)"
+If NAME is called, it combines its PLACE argument with the other
+arguments from ARGLIST using FUNC. For example:
+
+ (define-modify-macro incf (&optional (n 1)) +)
+
+You can replace this macro with `gv-letplace'."
(declare (debug
(&define name cl-lambda-list ;; should exclude &key
symbolp &optional stringp)))
diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el
index 456bace5b1b..58bfae5b503 100644
--- a/lisp/emacs-lisp/gv.el
+++ b/lisp/emacs-lisp/gv.el
@@ -111,7 +111,7 @@ DO must return an Elisp expression."
GETTER will be bound to a copyable expression that returns the value
of PLACE.
SETTER will be bound to a function that takes an expression V and returns
-and new expression that sets PLACE to V.
+a new expression that sets PLACE to V.
BODY should return some Elisp expression E manipulating PLACE via GETTER
and SETTER.
The returned value will then be an Elisp expression that first evaluates
@@ -194,7 +194,7 @@ well for simple place forms.
Assignments of VAL to (NAME ARGS...) are expanded by binding the argument
forms (VAL ARGS...) according to ARGLIST, then executing BODY, which must
return a Lisp form that does the assignment.
-The first arg in ARLIST (the one that receives VAL) receives an expression
+The first arg in ARGLIST (the one that receives VAL) receives an expression
which can do arbitrary things, whereas the other arguments are all guaranteed
to be pure and copyable. Example use:
(gv-define-setter aref (v a i) `(aset ,a ,i ,v))"
@@ -209,13 +209,20 @@ to be pure and copyable. Example use:
This macro is an easy-to-use substitute for `gv-define-expander' that works
well for simple place forms. Assignments of VAL to (NAME ARGS...) are
turned into calls of the form (SETTER ARGS... VAL).
+
If FIX-RETURN is non-nil, then SETTER is not assumed to return VAL and
-instead the assignment is turned into (prog1 VAL (SETTER ARGS... VAL))
+instead the assignment is turned into something equivalent to
+ \(let ((temp VAL))
+ (SETTER ARGS... temp)
+ temp)
so as to preserve the semantics of `setf'."
(declare (debug (sexp (&or symbolp lambda-expr) &optional sexp)))
- (let ((set-call `(cons ',setter (append args (list val)))))
`(gv-define-setter ,name (val &rest args)
- ,(if fix-return `(list 'prog1 val ,set-call) set-call))))
+ ,(if fix-return
+ `(macroexp-let2 nil v val
+ (cons ',setter (append args (list v)))
+ v)
+ `(cons ',setter (append args (list val))))))
;;; Typical operations on generalized variables.