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