* lisp/emacs-lisp/cl.el (dolist, dotimes, declare): Use advice-add to
[bpt/emacs.git] / lisp / emacs-lisp / cl.el
CommitLineData
6e9590e2 1;;; cl.el --- Compatibility aliases for the old CL library. -*- lexical-binding: t -*-
fcd73769 2
7c1898a7 3;; Copyright (C) 2012 Free Software Foundation, Inc.
fcd73769 4
7c1898a7 5;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
fcd73769
RS
6;; Keywords: extensions
7
8;; This file is part of GNU Emacs.
9
d6cba7ae 10;; GNU Emacs is free software: you can redistribute it and/or modify
fcd73769 11;; it under the terms of the GNU General Public License as published by
d6cba7ae
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
fcd73769
RS
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
d6cba7ae 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
fcd73769 22
07b3798c 23;;; Commentary:
fcd73769 24
7c1898a7
SM
25;; This is a compatibility file which provides the old names provided by CL
26;; before we cleaned up its namespace usage.
fcd73769 27
07b3798c 28;;; Code:
fcd73769 29
7c1898a7 30(require 'cl-lib)
de7e2b36 31(require 'macroexp)
7c1898a7
SM
32
33;; (defun cl--rename ()
34;; (let ((vdefs ())
35;; (fdefs ())
36;; (case-fold-search nil)
37;; (files '("cl.el" "cl-macs.el" "cl-seq.el" "cl-extra.el")))
38;; (dolist (file files)
39;; (with-current-buffer (find-file-noselect file)
40;; (goto-char (point-min))
41;; (while (re-search-forward
42;; "^(\\(def[^ \t\n]*\\) +'?\\(\\(\\sw\\|\\s_\\)+\\)" nil t)
43;; (let ((name (match-string-no-properties 2))
44;; (type (match-string-no-properties 1)))
45;; (unless (string-match-p "\\`cl-" name)
46;; (cond
47;; ((member type '("defvar" "defconst"))
48;; (unless (member name vdefs) (push name vdefs)))
49;; ((member type '("defun" "defsubst" "defalias" "defmacro"))
50;; (unless (member name fdefs) (push name fdefs)))
51;; ((member type '("def-edebug-spec" "defsetf" "define-setf-method"
52;; "define-compiler-macro"))
53;; nil)
54;; (t (error "Unknown type %S" type))))))))
55;; (let ((re (concat "\\_<" (regexp-opt (append vdefs fdefs)) "\\_>"))
56;; (conflicts ()))
57;; (dolist (file files)
58;; (with-current-buffer (find-file-noselect file)
59;; (goto-char (point-min))
60;; (while (re-search-forward re nil t)
61;; (replace-match "cl-\\&"))
62;; (save-buffer))))
63;; (with-current-buffer (find-file-noselect "cl-rename.el")
64;; (dolist (def vdefs)
65;; (insert (format "(defvaralias '%s 'cl-%s)\n" def def)))
66;; (dolist (def fdefs)
67;; (insert (format "(defalias '%s 'cl-%s)\n" def def)))
68;; (save-buffer))))
69
70;; (defun cl--unrename ()
71;; ;; Taken from "Naming Conventions" node of the doc.
72;; (let* ((names '(defun* defsubst* defmacro* function* member*
73;; assoc* rassoc* get* remove* delete*
74;; mapcar* sort* floor* ceiling* truncate*
75;; round* mod* rem* random*))
76;; (files '("cl.el" "cl-lib.el" "cl-macs.el" "cl-seq.el" "cl-extra.el"))
77;; (re (concat "\\_<cl-" (regexp-opt (mapcar #'symbol-name names))
78;; "\\_>")))
79;; (dolist (file files)
80;; (with-current-buffer (find-file-noselect file)
81;; (goto-char (point-min))
82;; (while (re-search-forward re nil t)
83;; (delete-region (1- (point)) (point)))
84;; (save-buffer)))))
2ee3d7f0
SM
85
86;;; Aliases to cl-lib's features.
87
7c1898a7
SM
88(dolist (var '(
89 ;; loop-result-var
90 ;; loop-result
91 ;; loop-initially
92 ;; loop-finally
93 ;; loop-bindings
94 ;; loop-args
95 ;; bind-inits
96 ;; bind-block
97 ;; lambda-list-keywords
98 float-negative-epsilon
99 float-epsilon
100 least-negative-normalized-float
101 least-positive-normalized-float
102 least-negative-float
103 least-positive-float
104 most-negative-float
105 most-positive-float
106 ;; custom-print-functions
107 ))
108 (defvaralias var (intern (format "cl-%s" var))))
109
110(dolist (fun '(
111 (get* . cl-get)
112 (random* . cl-random)
113 (rem* . cl-rem)
114 (mod* . cl-mod)
115 (round* . cl-round)
116 (truncate* . cl-truncate)
117 (ceiling* . cl-ceiling)
118 (floor* . cl-floor)
119 (rassoc* . cl-rassoc)
120 (assoc* . cl-assoc)
121 (member* . cl-member)
122 (delete* . cl-delete)
123 (remove* . cl-remove)
124 (defsubst* . cl-defsubst)
125 (sort* . cl-sort)
126 (function* . cl-function)
127 (defmacro* . cl-defmacro)
128 (defun* . cl-defun)
129 (mapcar* . cl-mapcar)
130
131 remprop
132 getf
133 tailp
134 list-length
135 nreconc
136 revappend
137 concatenate
138 subseq
139 random-state-p
140 make-random-state
141 signum
142 isqrt
143 lcm
144 gcd
145 notevery
146 notany
147 every
148 some
149 mapcon
150 mapcan
151 mapl
152 maplist
153 map
154 equalp
155 coerce
156 tree-equal
157 nsublis
158 sublis
159 nsubst-if-not
160 nsubst-if
161 nsubst
162 subst-if-not
163 subst-if
164 subsetp
165 nset-exclusive-or
166 set-exclusive-or
167 nset-difference
168 set-difference
169 nintersection
170 intersection
171 nunion
172 union
173 rassoc-if-not
174 rassoc-if
175 assoc-if-not
176 assoc-if
177 member-if-not
178 member-if
179 merge
180 stable-sort
181 search
182 mismatch
183 count-if-not
184 count-if
185 count
186 position-if-not
187 position-if
188 position
189 find-if-not
190 find-if
191 find
192 nsubstitute-if-not
193 nsubstitute-if
194 nsubstitute
195 substitute-if-not
196 substitute-if
197 substitute
198 delete-duplicates
199 remove-duplicates
200 delete-if-not
201 delete-if
202 remove-if-not
203 remove-if
204 replace
205 fill
206 reduce
207 compiler-macroexpand
208 define-compiler-macro
209 assert
210 check-type
211 typep
212 deftype
213 defstruct
7c1898a7
SM
214 callf2
215 callf
216 letf*
a464a6c7 217 ;; letf
7c1898a7
SM
218 rotatef
219 shiftf
220 remf
221 psetf
2ee3d7f0 222 (define-setf-method . define-setf-expander)
7c1898a7
SM
223 the
224 locally
225 multiple-value-setq
226 multiple-value-bind
7c1898a7
SM
227 symbol-macrolet
228 macrolet
7c1898a7
SM
229 progv
230 psetq
231 do-all-symbols
232 do-symbols
7c1898a7
SM
233 do*
234 do
235 loop
236 return-from
237 return
238 block
239 etypecase
240 typecase
241 ecase
242 case
243 load-time-value
244 eval-when
245 destructuring-bind
246 gentemp
247 gensym
248 pairlis
249 acons
250 subst
251 adjoin
252 copy-list
253 ldiff
254 list*
255 cddddr
256 cdddar
257 cddadr
258 cddaar
259 cdaddr
260 cdadar
261 cdaadr
262 cdaaar
263 cadddr
264 caddar
265 cadadr
266 cadaar
267 caaddr
268 caadar
269 caaadr
270 caaaar
271 cdddr
272 cddar
273 cdadr
274 cdaar
275 caddr
276 cadar
277 caadr
278 caaar
279 tenth
280 ninth
281 eighth
282 seventh
283 sixth
284 fifth
285 fourth
286 third
287 endp
288 rest
289 second
290 first
291 svref
292 copy-seq
293 evenp
294 oddp
295 minusp
296 plusp
297 floatp-safe
298 declaim
299 proclaim
300 nth-value
301 multiple-value-call
302 multiple-value-apply
303 multiple-value-list
304 values-list
305 values
306 pushnew
7c1898a7
SM
307 decf
308 incf
309 ))
310 (let ((new (if (consp fun) (prog1 (cdr fun) (setq fun (car fun)))
311 (intern (format "cl-%s" fun)))))
7abaf5cc 312 (defalias fun new)))
416a2c45 313
413d4689
SM
314(defun cl--wrap-in-nil-block (fun &rest args)
315 `(cl-block nil ,(apply fun args)))
316(advice-add 'dolist :around #'cl--wrap-in-nil-block)
317(advice-add 'dotimes :around #'cl--wrap-in-nil-block)
318
319(defun cl--pass-args-to-cl-declare (&rest specs)
320 (macroexpand `(cl-declare ,@specs)))
321(advice-add 'declare :after #'cl--pass-args-to-cl-declare)
322
2ee3d7f0
SM
323;;; Features provided a bit differently in Elisp.
324
325;; First, the old lexical-let is now better served by `lexical-binding', tho
326;; it's not 100% compatible.
327
de7e2b36
SM
328(defvar cl-closure-vars nil)
329(defvar cl--function-convert-cache nil)
330
331(defun cl--function-convert (f)
332 "Special macro-expander for special cases of (function F).
333The two cases that are handled are:
334- closure-conversion of lambda expressions for `lexical-let'.
335- renaming of F when it's a function defined via `cl-labels' or `labels'."
336 (require 'cl-macs)
bb3faf5b 337 (declare-function cl--expr-contains-any "cl-macs" (x y))
de7e2b36
SM
338 (cond
339 ;; ¡¡Big Ugly Hack!! We can't use a compiler-macro because those are checked
340 ;; *after* handling `function', but we want to stop macroexpansion from
341 ;; being applied infinitely, so we use a cache to return the exact `form'
342 ;; being expanded even though we don't receive it.
343 ((eq f (car cl--function-convert-cache)) (cdr cl--function-convert-cache))
344 ((eq (car-safe f) 'lambda)
345 (let ((body (mapcar (lambda (f)
346 (macroexpand-all f macroexpand-all-environment))
347 (cddr f))))
348 (if (and cl-closure-vars
349 (cl--expr-contains-any body cl-closure-vars))
350 (let* ((new (mapcar 'cl-gensym cl-closure-vars))
351 (sub (cl-pairlis cl-closure-vars new)) (decls nil))
352 (while (or (stringp (car body))
353 (eq (car-safe (car body)) 'interactive))
354 (push (list 'quote (pop body)) decls))
355 (put (car (last cl-closure-vars)) 'used t)
356 `(list 'lambda '(&rest --cl-rest--)
357 ,@(cl-sublis sub (nreverse decls))
358 (list 'apply
359 (list 'quote
360 #'(lambda ,(append new (cadr f))
361 ,@(cl-sublis sub body)))
362 ,@(nconc (mapcar (lambda (x) `(list 'quote ,x))
363 cl-closure-vars)
364 '((quote --cl-rest--))))))
365 (let* ((newf `(lambda ,(cadr f) ,@body))
366 (res `(function ,newf)))
367 (setq cl--function-convert-cache (cons newf res))
368 res))))
369 (t
370 (let ((found (assq f macroexpand-all-environment)))
371 (if (and found (ignore-errors
372 (eq (cadr (cl-caddr found)) 'cl-labels-args)))
373 (cadr (cl-caddr (cl-cadddr found)))
374 (let ((res `(function ,f)))
375 (setq cl--function-convert-cache (cons f res))
376 res))))))
377
378(defmacro lexical-let (bindings &rest body)
379 "Like `let', but lexically scoped.
380The main visible difference is that lambdas inside BODY will create
381lexical closures as in Common Lisp.
382\n(fn BINDINGS BODY)"
383 (declare (indent 1) (debug let))
384 (let* ((cl-closure-vars cl-closure-vars)
385 (vars (mapcar (function
386 (lambda (x)
387 (or (consp x) (setq x (list x)))
388 (push (make-symbol (format "--cl-%s--" (car x)))
389 cl-closure-vars)
390 (set (car cl-closure-vars) [bad-lexical-ref])
391 (list (car x) (cadr x) (car cl-closure-vars))))
392 bindings))
393 (ebody
394 (macroexpand-all
395 `(cl-symbol-macrolet
396 ,(mapcar (lambda (x)
397 `(,(car x) (symbol-value ,(cl-caddr x))))
398 vars)
399 ,@body)
400 (cons (cons 'function #'cl--function-convert)
401 macroexpand-all-environment))))
402 (if (not (get (car (last cl-closure-vars)) 'used))
403 ;; Turn (let ((foo (cl-gensym)))
404 ;; (set foo <val>) ...(symbol-value foo)...)
405 ;; into (let ((foo <val>)) ...(symbol-value 'foo)...).
406 ;; This is good because it's more efficient but it only works with
407 ;; dynamic scoping, since with lexical scoping we'd need
408 ;; (let ((foo <val>)) ...foo...).
409 `(progn
410 ,@(mapcar (lambda (x) `(defvar ,(cl-caddr x))) vars)
411 (let ,(mapcar (lambda (x) (list (cl-caddr x) (cadr x))) vars)
412 ,(cl-sublis (mapcar (lambda (x)
413 (cons (cl-caddr x)
414 `',(cl-caddr x)))
415 vars)
416 ebody)))
417 `(let ,(mapcar (lambda (x)
418 (list (cl-caddr x)
419 `(make-symbol ,(format "--%s--" (car x)))))
420 vars)
2ee3d7f0 421 (setf ,@(apply #'append
de7e2b36
SM
422 (mapcar (lambda (x)
423 (list `(symbol-value ,(cl-caddr x)) (cadr x)))
424 vars)))
425 ,ebody))))
426
427(defmacro lexical-let* (bindings &rest body)
428 "Like `let*', but lexically scoped.
429The main visible difference is that lambdas inside BODY, and in
430successive bindings within BINDINGS, will create lexical closures
431as in Common Lisp. This is similar to the behavior of `let*' in
432Common Lisp.
433\n(fn BINDINGS BODY)"
434 (declare (indent 1) (debug let))
435 (if (null bindings) (cons 'progn body)
436 (setq bindings (reverse bindings))
437 (while bindings
438 (setq body (list `(lexical-let (,(pop bindings)) ,@body))))
439 (car body)))
440
441;; This should really have some way to shadow 'byte-compile properties, etc.
de7e2b36 442(defmacro flet (bindings &rest body)
d5c6faf9
SM
443 "Make temporary overriding function definitions.
444This is an analogue of a dynamically scoped `let' that operates on the function
445cell of FUNCs rather than their value cell.
446If you want the Common-Lisp style of `flet', you should use `cl-flet'.
447The FORMs are evaluated with the specified function definitions in place,
448then the definitions are undone (the FUNCs go back to their previous
449definitions, or lack thereof).
de7e2b36
SM
450
451\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
a464a6c7 452 (declare (indent 1) (debug cl-flet)
277f0cfa 453 (obsolete "use either `cl-flet' or `cl-letf'." "24.3"))
a464a6c7
SM
454 `(letf ,(mapcar
455 (lambda (x)
456 (if (or (and (fboundp (car x))
457 (eq (car-safe (symbol-function (car x))) 'macro))
458 (cdr (assq (car x) macroexpand-all-environment)))
459 (error "Use `labels', not `flet', to rebind macro names"))
460 (let ((func `(cl-function
461 (lambda ,(cadr x)
462 (cl-block ,(car x) ,@(cddr x))))))
463 (when (cl--compiling-file)
464 ;; Bug#411. It would be nice to fix this.
465 (and (get (car x) 'byte-compile)
466 (error "Byte-compiling a redefinition of `%s' \
de7e2b36 467will not work - use `labels' instead" (symbol-name (car x))))
a464a6c7
SM
468 ;; FIXME This affects the rest of the file, when it
469 ;; should be restricted to the flet body.
470 (and (boundp 'byte-compile-function-environment)
471 (push (cons (car x) (eval func))
472 byte-compile-function-environment)))
473 (list `(symbol-function ',(car x)) func)))
474 bindings)
de7e2b36
SM
475 ,@body))
476
477(defmacro labels (bindings &rest body)
478 "Make temporary function bindings.
a464a6c7
SM
479Like `cl-labels' except that the lexical scoping is handled via `lexical-let'
480rather than relying on `lexical-binding'."
2a1e2476 481 (declare (indent 1) (debug cl-flet) (obsolete cl-labels "24.3"))
de7e2b36
SM
482 (let ((vars nil) (sets nil) (newenv macroexpand-all-environment))
483 (dolist (binding bindings)
484 ;; It's important that (not (eq (symbol-name var1) (symbol-name var2)))
485 ;; because these var's *names* get added to the macro-environment.
486 (let ((var (make-symbol (format "--cl-%s--" (car binding)))))
487 (push var vars)
488 (push `(cl-function (lambda . ,(cdr binding))) sets)
489 (push var sets)
490 (push (cons (car binding)
491 `(lambda (&rest cl-labels-args)
492 (cl-list* 'funcall ',var
493 cl-labels-args)))
494 newenv)))
495 (macroexpand-all `(lexical-let ,vars (setq ,@sets) ,@body) newenv)))
496
2ee3d7f0
SM
497;; Generalized variables are provided by gv.el, but some details are
498;; not 100% compatible: not worth the trouble to add them to cl-lib.el, but we
04901786 499;; still need to support old users of cl.el.
2ee3d7f0 500
a464a6c7
SM
501(defmacro cl--symbol-function (symbol)
502 "Like `symbol-function' but return `cl--unbound' if not bound."
503 ;; (declare (gv-setter (lambda (store)
504 ;; `(if (eq ,store 'cl--unbound)
505 ;; (fmakunbound ,symbol) (fset ,symbol ,store)))))
506 `(if (fboundp ,symbol) (symbol-function ,symbol) 'cl--unbound))
507(gv-define-setter cl--symbol-function (store symbol)
508 `(if (eq ,store 'cl--unbound) (fmakunbound ,symbol) (fset ,symbol ,store)))
2ee3d7f0
SM
509
510(defmacro letf (bindings &rest body)
a464a6c7 511 "Dynamically scoped let-style bindings for places.
4ddedf94
GM
512For more details, see `cl-letf'. This macro behaves like that one
513in almost every respect (apart from details that relate to some
514deprecated usage of `symbol-function' in place forms)." ; bug#12760
c606253c 515 (declare (indent 1) (debug cl-letf))
a464a6c7
SM
516 ;; Like cl-letf, but with special handling of symbol-function.
517 `(cl-letf ,(mapcar (lambda (x) (if (eq (car-safe (car x)) 'symbol-function)
518 `((cl--symbol-function ,@(cdar x)) ,@(cdr x))
519 x))
520 bindings)
521 ,@body))
2ee3d7f0 522
36cec983
SM
523(defun cl--gv-adapt (cl-gv do)
524 ;; This function is used by all .elc files that use define-setf-expander and
2a1e2476 525 ;; were compiled with Emacs>=24.3.
2ee3d7f0
SM
526 (let ((vars (nth 0 cl-gv))
527 (vals (nth 1 cl-gv))
528 (binds ())
529 (substs ()))
530 ;; Use cl-sublis as was done in cl-setf-do-modify.
531 (while vars
532 (if (macroexp-copyable-p (car vals))
533 (push (cons (pop vars) (pop vals)) substs)
534 (push (list (pop vars) (pop vals)) binds)))
535 (macroexp-let*
536 binds
537 (funcall do (cl-sublis substs (nth 4 cl-gv))
538 ;; We'd like to do something like
539 ;; (lambda ,(nth 2 cl-gv) ,(nth 3 cl-gv)).
540 (lambda (exp)
541 (macroexp-let2 macroexp-copyable-p v exp
542 (cl-sublis (cons (cons (car (nth 2 cl-gv)) v)
543 substs)
544 (nth 3 cl-gv))))))))
545
546(defmacro define-setf-expander (name arglist &rest body)
547 "Define a `setf' method.
031b2ea7
GM
548This method shows how to handle `setf's to places of the form
549\(NAME ARGS...). The argument forms ARGS are bound according to
550ARGLIST, as if NAME were going to be expanded as a macro, then
551the BODY forms are executed and must return a list of five elements:
552a temporary-variables list, a value-forms list, a store-variables list
553\(of length one), a store-form, and an access- form.
554
555See `gv-define-expander', and `gv-define-setter' for better and
556simpler ways to define setf-methods."
2ee3d7f0
SM
557 (declare (debug
558 (&define name cl-lambda-list cl-declarations-or-string def-body)))
559 `(progn
560 ,@(if (stringp (car body))
561 (list `(put ',name 'setf-documentation ,(pop body))))
562 (gv-define-expander ,name
563 (cl-function
564 (lambda (do ,@arglist)
565 (cl--gv-adapt (progn ,@body) do))))))
566
567(defmacro defsetf (name arg1 &rest args)
568 "Define a `setf' method.
031b2ea7
GM
569This macro is an easy-to-use substitute for `define-setf-expander'
570that works well for simple place forms.
571
572In the simple `defsetf' form, `setf's of the form (setf (NAME
573ARGS...) VAL) are transformed to function or macro calls of the
574form (FUNC ARGS... VAL). For example:
2ee3d7f0 575
a0ccbcbd 576 (defsetf aref aset)
2ee3d7f0 577
031b2ea7
GM
578You can replace this form with `gv-define-simple-setter'.
579
a0ccbcbd 580Alternate form: (defsetf NAME ARGLIST (STORE) BODY...).
031b2ea7
GM
581
582Here, the above `setf' call is expanded by binding the argument
583forms ARGS according to ARGLIST, binding the value form VAL to
584STORE, then executing BODY, which must return a Lisp form that
585does the necessary `setf' operation. Actually, ARGLIST and STORE
586may be bound to temporary variables which are introduced
587automatically to preserve proper execution order of the arguments.
588For example:
2ee3d7f0 589
a0ccbcbd 590 (defsetf nth (n x) (v) `(setcar (nthcdr ,n ,x) ,v))
2ee3d7f0 591
031b2ea7
GM
592You can replace this form with `gv-define-setter'.
593
2ee3d7f0
SM
594\(fn NAME [FUNC | ARGLIST (STORE) BODY...])"
595 (declare (debug
596 (&define name
597 [&or [symbolp &optional stringp]
598 [cl-lambda-list (symbolp)]]
599 cl-declarations-or-string def-body)))
600 (if (and (listp arg1) (consp args))
601 ;; Like `gv-define-setter' but with `cl-function'.
602 `(gv-define-expander ,name
603 (lambda (do &rest args)
604 (gv--defsetter ',name
605 (cl-function
606 (lambda (,@(car args) ,@arg1) ,@(cdr args)))
607 do args)))
d57c286e 608 `(gv-define-simple-setter ,name ,arg1 ,(car args))))
2ee3d7f0
SM
609
610;; FIXME: CL used to provide a setf method for `apply', but I haven't been able
611;; to find a case where it worked. The code below tries to handle it as well.
612;; (defun cl--setf-apply (form last-witness last)
613;; (cond
614;; ((not (consp form)) form)
615;; ((eq (ignore-errors (car (last form))) last-witness)
616;; `(apply #',(car form) ,@(butlast (cdr form)) ,last))
617;; ((and (memq (car form) '(let let*))
618;; (rassoc (list last-witness) (cadr form)))
619;; (let ((rebind (rassoc (list last-witness) (cadr form))))
620;; `(,(car form) ,(remq rebind (cadr form))
621;; ,@(mapcar (lambda (form) (cl--setf-apply form (car rebind) last))
622;; (cddr form)))))
623;; (t (mapcar (lambda (form) (cl--setf-apply form last-witness last)) form))))
624;; (gv-define-setter apply (val fun &rest args)
625;; (pcase fun (`#',(and (pred symbolp) f) (setq fun f))
626;; (_ (error "First arg to apply in setf is not #'SYM: %S" fun)))
627;; (let* ((butlast (butlast args))
628;; (last (car (last args)))
629;; (last-witness (make-symbol "--cl-tailarg--"))
630;; (setter (macroexpand `(setf (,fun ,@butlast ,last-witness) ,val)
631;; macroexpand-all-environment)))
632;; (cl--setf-apply setter last-witness last)))
633
634
635;; FIXME: CL used to provide get-setf-method, which was used by some
636;; setf-expanders, but now that we use gv.el, it is a lot more difficult
637;; and in general impossible to provide get-setf-method. Hopefully, it
638;; won't be needed. If needed, we'll have to do something nasty along the
639;; lines of
640;; (defun get-setf-method (place &optional env)
641;; (let* ((witness (list 'cl-gsm))
642;; (expansion (gv-letplace (getter setter) place
643;; `(,witness ,getter ,(funcall setter witness)))))
644;; ...find "let prefix" of expansion, extract getter and setter from
645;; ...the rest, and build the 5-tuple))
2a1e2476 646(make-obsolete 'get-setf-method 'gv-letplace "24.3")
2ee3d7f0
SM
647
648(defmacro define-modify-macro (name arglist func &optional doc)
649 "Define a `setf'-like modify macro.
031b2ea7
GM
650If NAME is called, it combines its PLACE argument with the other
651arguments from ARGLIST using FUNC. For example:
652
653 (define-modify-macro incf (&optional (n 1)) +)
654
655You can replace this macro with `gv-letplace'."
2ee3d7f0
SM
656 (declare (debug
657 (&define name cl-lambda-list ;; should exclude &key
658 symbolp &optional stringp)))
659 (if (memq '&key arglist)
660 (error "&key not allowed in define-modify-macro"))
661 (let ((place (make-symbol "--cl-place--")))
662 `(cl-defmacro ,name (,place ,@arglist)
663 ,doc
664 (,(if (memq '&rest arglist) #'cl-list* #'list)
665 #'cl-callf ',func ,place
666 ,@(cl--arglist-args arglist)))))
667
668;;; Additional compatibility code.
6fa6c4ae
SM
669;; For names that were clean but really aren't needed any more.
670
2a1e2476 671(define-obsolete-function-alias 'cl-macroexpand 'macroexpand "24.3")
de7e2b36 672(define-obsolete-variable-alias 'cl-macro-environment
2a1e2476
GM
673 'macroexpand-all-environment "24.3")
674(define-obsolete-function-alias 'cl-macroexpand-all 'macroexpand-all "24.3")
6fa6c4ae
SM
675
676;;; Hash tables.
677;; This is just kept for compatibility with code byte-compiled by Emacs-20.
678
679;; No idea if this might still be needed.
6e9590e2 680(defun cl-not-hash-table (x &optional y &rest _z)
2a1e2476 681 (declare (obsolete nil "24.3"))
6fa6c4ae
SM
682 (signal 'wrong-type-argument (list 'cl-hash-table-p (or y x))))
683
684(defvar cl-builtin-gethash (symbol-function 'gethash))
2a1e2476 685(make-obsolete-variable 'cl-builtin-gethash nil "24.3")
6fa6c4ae 686(defvar cl-builtin-remhash (symbol-function 'remhash))
2a1e2476 687(make-obsolete-variable 'cl-builtin-remhash nil "24.3")
6fa6c4ae 688(defvar cl-builtin-clrhash (symbol-function 'clrhash))
2a1e2476 689(make-obsolete-variable 'cl-builtin-clrhash nil "24.3")
6fa6c4ae
SM
690(defvar cl-builtin-maphash (symbol-function 'maphash))
691
2a1e2476
GM
692(make-obsolete-variable 'cl-builtin-maphash nil "24.3")
693(define-obsolete-function-alias 'cl-map-keymap 'map-keymap "24.3")
694(define-obsolete-function-alias 'cl-copy-tree 'copy-tree "24.3")
695(define-obsolete-function-alias 'cl-gethash 'gethash "24.3")
696(define-obsolete-function-alias 'cl-puthash 'puthash "24.3")
697(define-obsolete-function-alias 'cl-remhash 'remhash "24.3")
698(define-obsolete-function-alias 'cl-clrhash 'clrhash "24.3")
699(define-obsolete-function-alias 'cl-maphash 'maphash "24.3")
700(define-obsolete-function-alias 'cl-make-hash-table 'make-hash-table "24.3")
701(define-obsolete-function-alias 'cl-hash-table-p 'hash-table-p "24.3")
702(define-obsolete-function-alias 'cl-hash-table-count 'hash-table-count "24.3")
6fa6c4ae 703
4250fdf5 704(define-obsolete-function-alias 'cl-map-keymap-recursively
2a1e2476
GM
705 'cl--map-keymap-recursively "24.3")
706(define-obsolete-function-alias 'cl-map-intervals 'cl--map-intervals "24.3")
707(define-obsolete-function-alias 'cl-map-extents 'cl--map-overlays "24.3")
4250fdf5 708
bb3faf5b 709(defun cl-maclisp-member (item list)
2a1e2476 710 (declare (obsolete member "24.3"))
bb3faf5b
SM
711 (while (and list (not (equal item (car list)))) (setq list (cdr list)))
712 list)
713
2ee3d7f0
SM
714;; Used in the expansion of the old `defstruct'.
715(defun cl-struct-setf-expander (x name accessor pred-form pos)
2a1e2476 716 (declare (obsolete nil "24.3"))
2ee3d7f0
SM
717 (let* ((temp (make-symbol "--cl-x--")) (store (make-symbol "--cl-store--")))
718 (list (list temp) (list x) (list store)
719 `(progn
720 ,@(and pred-form
721 (list `(or ,(cl-subst temp 'cl-x pred-form)
722 (error ,(format
723 "%s storing a non-%s"
724 accessor name)))))
725 ,(if (eq (car (get name 'cl-struct-type)) 'vector)
726 `(aset ,temp ,pos ,store)
727 `(setcar
728 ,(if (<= pos 5)
729 (let ((xx temp))
730 (while (>= (setq pos (1- pos)) 0)
731 (setq xx `(cdr ,xx)))
732 xx)
733 `(nthcdr ,pos ,temp))
734 ,store)))
735 (list accessor temp))))
736
7467c796 737(provide 'cl)
fcd73769 738;;; cl.el ends here