Provide generalized variables in core Elisp.
[bpt/emacs.git] / lisp / emacs-lisp / cl.el
CommitLineData
7c1898a7 1;;; cl.el --- Compatibility aliases for the old CL library.
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*
217 letf
218 rotatef
219 shiftf
220 remf
221 psetf
2ee3d7f0 222 (define-setf-method . define-setf-expander)
7c1898a7
SM
223 declare
224 the
225 locally
226 multiple-value-setq
227 multiple-value-bind
7c1898a7
SM
228 symbol-macrolet
229 macrolet
7c1898a7
SM
230 flet
231 progv
232 psetq
233 do-all-symbols
234 do-symbols
235 dotimes
236 dolist
237 do*
238 do
239 loop
240 return-from
241 return
242 block
243 etypecase
244 typecase
245 ecase
246 case
247 load-time-value
248 eval-when
249 destructuring-bind
250 gentemp
251 gensym
252 pairlis
253 acons
254 subst
255 adjoin
256 copy-list
257 ldiff
258 list*
259 cddddr
260 cdddar
261 cddadr
262 cddaar
263 cdaddr
264 cdadar
265 cdaadr
266 cdaaar
267 cadddr
268 caddar
269 cadadr
270 cadaar
271 caaddr
272 caadar
273 caaadr
274 caaaar
275 cdddr
276 cddar
277 cdadr
278 cdaar
279 caddr
280 cadar
281 caadr
282 caaar
283 tenth
284 ninth
285 eighth
286 seventh
287 sixth
288 fifth
289 fourth
290 third
291 endp
292 rest
293 second
294 first
295 svref
296 copy-seq
297 evenp
298 oddp
299 minusp
300 plusp
301 floatp-safe
302 declaim
303 proclaim
304 nth-value
305 multiple-value-call
306 multiple-value-apply
307 multiple-value-list
308 values-list
309 values
310 pushnew
7c1898a7
SM
311 decf
312 incf
313 ))
314 (let ((new (if (consp fun) (prog1 (cdr fun) (setq fun (car fun)))
315 (intern (format "cl-%s" fun)))))
316 (defalias fun new)
317 ;; If `cl-foo' is declare inline, then make `foo' inline as well, and
57a7d507 318 ;; similarly. Same for edebug specifications, indent rules and
7c1898a7
SM
319 ;; doc-string position.
320 ;; FIXME: For most of them, we should instead follow aliases
321 ;; where applicable.
57a7d507 322 (dolist (prop '(byte-optimizer doc-string-elt edebug-form-spec
7c1898a7
SM
323 lisp-indent-function))
324 (if (get new prop)
325 (put fun prop (get new prop))))))
416a2c45 326
2ee3d7f0
SM
327;;; Features provided a bit differently in Elisp.
328
329;; First, the old lexical-let is now better served by `lexical-binding', tho
330;; it's not 100% compatible.
331
de7e2b36
SM
332(defvar cl-closure-vars nil)
333(defvar cl--function-convert-cache nil)
334
335(defun cl--function-convert (f)
336 "Special macro-expander for special cases of (function F).
337The two cases that are handled are:
338- closure-conversion of lambda expressions for `lexical-let'.
339- renaming of F when it's a function defined via `cl-labels' or `labels'."
340 (require 'cl-macs)
bb3faf5b 341 (declare-function cl--expr-contains-any "cl-macs" (x y))
de7e2b36
SM
342 (cond
343 ;; ¡¡Big Ugly Hack!! We can't use a compiler-macro because those are checked
344 ;; *after* handling `function', but we want to stop macroexpansion from
345 ;; being applied infinitely, so we use a cache to return the exact `form'
346 ;; being expanded even though we don't receive it.
347 ((eq f (car cl--function-convert-cache)) (cdr cl--function-convert-cache))
348 ((eq (car-safe f) 'lambda)
349 (let ((body (mapcar (lambda (f)
350 (macroexpand-all f macroexpand-all-environment))
351 (cddr f))))
352 (if (and cl-closure-vars
353 (cl--expr-contains-any body cl-closure-vars))
354 (let* ((new (mapcar 'cl-gensym cl-closure-vars))
355 (sub (cl-pairlis cl-closure-vars new)) (decls nil))
356 (while (or (stringp (car body))
357 (eq (car-safe (car body)) 'interactive))
358 (push (list 'quote (pop body)) decls))
359 (put (car (last cl-closure-vars)) 'used t)
360 `(list 'lambda '(&rest --cl-rest--)
361 ,@(cl-sublis sub (nreverse decls))
362 (list 'apply
363 (list 'quote
364 #'(lambda ,(append new (cadr f))
365 ,@(cl-sublis sub body)))
366 ,@(nconc (mapcar (lambda (x) `(list 'quote ,x))
367 cl-closure-vars)
368 '((quote --cl-rest--))))))
369 (let* ((newf `(lambda ,(cadr f) ,@body))
370 (res `(function ,newf)))
371 (setq cl--function-convert-cache (cons newf res))
372 res))))
373 (t
374 (let ((found (assq f macroexpand-all-environment)))
375 (if (and found (ignore-errors
376 (eq (cadr (cl-caddr found)) 'cl-labels-args)))
377 (cadr (cl-caddr (cl-cadddr found)))
378 (let ((res `(function ,f)))
379 (setq cl--function-convert-cache (cons f res))
380 res))))))
381
382(defmacro lexical-let (bindings &rest body)
383 "Like `let', but lexically scoped.
384The main visible difference is that lambdas inside BODY will create
385lexical closures as in Common Lisp.
386\n(fn BINDINGS BODY)"
387 (declare (indent 1) (debug let))
388 (let* ((cl-closure-vars cl-closure-vars)
389 (vars (mapcar (function
390 (lambda (x)
391 (or (consp x) (setq x (list x)))
392 (push (make-symbol (format "--cl-%s--" (car x)))
393 cl-closure-vars)
394 (set (car cl-closure-vars) [bad-lexical-ref])
395 (list (car x) (cadr x) (car cl-closure-vars))))
396 bindings))
397 (ebody
398 (macroexpand-all
399 `(cl-symbol-macrolet
400 ,(mapcar (lambda (x)
401 `(,(car x) (symbol-value ,(cl-caddr x))))
402 vars)
403 ,@body)
404 (cons (cons 'function #'cl--function-convert)
405 macroexpand-all-environment))))
406 (if (not (get (car (last cl-closure-vars)) 'used))
407 ;; Turn (let ((foo (cl-gensym)))
408 ;; (set foo <val>) ...(symbol-value foo)...)
409 ;; into (let ((foo <val>)) ...(symbol-value 'foo)...).
410 ;; This is good because it's more efficient but it only works with
411 ;; dynamic scoping, since with lexical scoping we'd need
412 ;; (let ((foo <val>)) ...foo...).
413 `(progn
414 ,@(mapcar (lambda (x) `(defvar ,(cl-caddr x))) vars)
415 (let ,(mapcar (lambda (x) (list (cl-caddr x) (cadr x))) vars)
416 ,(cl-sublis (mapcar (lambda (x)
417 (cons (cl-caddr x)
418 `',(cl-caddr x)))
419 vars)
420 ebody)))
421 `(let ,(mapcar (lambda (x)
422 (list (cl-caddr x)
423 `(make-symbol ,(format "--%s--" (car x)))))
424 vars)
2ee3d7f0 425 (setf ,@(apply #'append
de7e2b36
SM
426 (mapcar (lambda (x)
427 (list `(symbol-value ,(cl-caddr x)) (cadr x)))
428 vars)))
429 ,ebody))))
430
431(defmacro lexical-let* (bindings &rest body)
432 "Like `let*', but lexically scoped.
433The main visible difference is that lambdas inside BODY, and in
434successive bindings within BINDINGS, will create lexical closures
435as in Common Lisp. This is similar to the behavior of `let*' in
436Common Lisp.
437\n(fn BINDINGS BODY)"
438 (declare (indent 1) (debug let))
439 (if (null bindings) (cons 'progn body)
440 (setq bindings (reverse bindings))
441 (while bindings
442 (setq body (list `(lexical-let (,(pop bindings)) ,@body))))
443 (car body)))
444
445;; This should really have some way to shadow 'byte-compile properties, etc.
de7e2b36
SM
446(defmacro flet (bindings &rest body)
447 "Make temporary function definitions.
448This is an analogue of `let' that operates on the function cell of FUNC
449rather than its value cell. The FORMs are evaluated with the specified
450function definitions in place, then the definitions are undone (the FUNCs
451go back to their previous definitions, or lack thereof).
452
453\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
454 (declare (indent 1) (debug cl-flet))
2ee3d7f0 455 `(letf* ,(mapcar
de7e2b36
SM
456 (lambda (x)
457 (if (or (and (fboundp (car x))
458 (eq (car-safe (symbol-function (car x))) 'macro))
459 (cdr (assq (car x) macroexpand-all-environment)))
460 (error "Use `labels', not `flet', to rebind macro names"))
461 (let ((func `(cl-function
462 (lambda ,(cadr x)
463 (cl-block ,(car x) ,@(cddr x))))))
bb3faf5b 464 (when (cl--compiling-file)
de7e2b36
SM
465 ;; Bug#411. It would be nice to fix this.
466 (and (get (car x) 'byte-compile)
467 (error "Byte-compiling a redefinition of `%s' \
468will not work - use `labels' instead" (symbol-name (car x))))
469 ;; FIXME This affects the rest of the file, when it
470 ;; should be restricted to the flet body.
471 (and (boundp 'byte-compile-function-environment)
472 (push (cons (car x) (eval func))
473 byte-compile-function-environment)))
474 (list `(symbol-function ',(car x)) func)))
475 bindings)
476 ,@body))
477
478(defmacro labels (bindings &rest body)
479 "Make temporary function bindings.
480This is like `flet', except the bindings are lexical instead of dynamic.
481Unlike `flet', this macro is fully compliant with the Common Lisp standard.
482
483\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
484 (declare (indent 1) (debug cl-flet))
485 (let ((vars nil) (sets nil) (newenv macroexpand-all-environment))
486 (dolist (binding bindings)
487 ;; It's important that (not (eq (symbol-name var1) (symbol-name var2)))
488 ;; because these var's *names* get added to the macro-environment.
489 (let ((var (make-symbol (format "--cl-%s--" (car binding)))))
490 (push var vars)
491 (push `(cl-function (lambda . ,(cdr binding))) sets)
492 (push var sets)
493 (push (cons (car binding)
494 `(lambda (&rest cl-labels-args)
495 (cl-list* 'funcall ',var
496 cl-labels-args)))
497 newenv)))
498 (macroexpand-all `(lexical-let ,vars (setq ,@sets) ,@body) newenv)))
499
2ee3d7f0
SM
500;; Generalized variables are provided by gv.el, but some details are
501;; not 100% compatible: not worth the trouble to add them to cl-lib.el, but we
502;; still to support old users of cl.el.
503
504(defun cl--letf (bindings simplebinds binds body)
505 ;; It's not quite clear what the semantics of let! should be.
506 ;; E.g. in (let! ((PLACE1 VAL1) (PLACE2 VAL2)) BODY), while it's clear
507 ;; that the actual assignments ("bindings") should only happen after
508 ;; evaluating VAL1 and VAL2, it's not clear when the sub-expressions of
509 ;; PLACE1 and PLACE2 should be evaluated. Should we have
510 ;; PLACE1; VAL1; PLACE2; VAL2; bind1; bind2
511 ;; or
512 ;; VAL1; VAL2; PLACE1; PLACE2; bind1; bind2
513 ;; or
514 ;; VAL1; VAL2; PLACE1; bind1; PLACE2; bind2
515 ;; Common-Lisp's `psetf' does the first, so we'll do the same.
516 (if (null bindings)
517 (if (and (null binds) (null simplebinds)) (macroexp-progn body)
518 `(let* (,@(mapcar (lambda (x)
519 (pcase-let ((`(,vold ,getter ,_setter ,_vnew) x))
520 (list vold getter)))
521 binds)
522 ,@simplebinds)
523 (unwind-protect
524 ,(macroexp-progn (append
525 (mapcar (lambda (x) (pcase x
526 (`(,_vold ,_getter ,setter ,vnew)
527 (funcall setter vnew))))
528 binds)
529 body))
530 ,@(mapcar (lambda (x) (pcase-let ((`(,vold ,_getter ,setter ,_vnew) x))
531 (funcall setter vold)))
532 binds))))
533 (let ((binding (car bindings)))
534 (gv-letplace (getter setter) (car binding)
535 (macroexp-let2 nil vnew (cadr binding)
536 (if (symbolp (car binding))
537 ;; Special-case for simple variables.
538 (cl--letf (cdr bindings)
539 (cons `(,getter ,(if (cdr binding) vnew getter))
540 simplebinds)
541 binds body)
542 (cl--letf (cdr bindings) simplebinds
543 (cons `(,(make-symbol "old") ,getter ,setter
544 ,@(if (cdr binding) (list vnew)))
545 binds)
546 body)))))))
547
548(defmacro letf (bindings &rest body)
549 "Temporarily bind to PLACEs.
550This is the analogue of `let', but with generalized variables (in the
551sense of `setf') for the PLACEs. Each PLACE is set to the corresponding
552VALUE, then the BODY forms are executed. On exit, either normally or
553because of a `throw' or error, the PLACEs are set back to their original
554values. Note that this macro is *not* available in Common Lisp.
555As a special case, if `(PLACE)' is used instead of `(PLACE VALUE)',
556the PLACE is not modified before executing BODY.
557
558\(fn ((PLACE VALUE) ...) BODY...)"
559 (declare (indent 1) (debug ((&rest (gate gv-place &optional form)) body)))
560 (cl--letf bindings () () body))
561
562(defun cl--letf* (bindings body)
563 (if (null bindings)
564 (macroexp-progn body)
565 (let ((binding (car bindings)))
566 (if (symbolp (car binding))
567 ;; Special-case for simple variables.
568 (macroexp-let* (list (if (cdr binding) binding
569 (list (car binding) (car binding))))
570 (cl--letf* (cdr bindings) body))
571 (gv-letplace (getter setter) (car binding)
572 (macroexp-let2 macroexp-copyable-p vnew (cadr binding)
573 (macroexp-let2 nil vold getter
574 `(unwind-protect
575 (progn
576 ,(if (cdr binding) (funcall setter vnew))
577 ,(cl--letf* (cdr bindings) body))
578 ,(funcall setter vold)))))))))
579
580(defmacro letf* (bindings &rest body)
581 (declare (indent 1) (debug letf))
582 (cl--letf* bindings body))
583
584(defun cl--gv-adapt (cl-gv do) ;FIXME: needed during setf expansion!
585 (let ((vars (nth 0 cl-gv))
586 (vals (nth 1 cl-gv))
587 (binds ())
588 (substs ()))
589 ;; Use cl-sublis as was done in cl-setf-do-modify.
590 (while vars
591 (if (macroexp-copyable-p (car vals))
592 (push (cons (pop vars) (pop vals)) substs)
593 (push (list (pop vars) (pop vals)) binds)))
594 (macroexp-let*
595 binds
596 (funcall do (cl-sublis substs (nth 4 cl-gv))
597 ;; We'd like to do something like
598 ;; (lambda ,(nth 2 cl-gv) ,(nth 3 cl-gv)).
599 (lambda (exp)
600 (macroexp-let2 macroexp-copyable-p v exp
601 (cl-sublis (cons (cons (car (nth 2 cl-gv)) v)
602 substs)
603 (nth 3 cl-gv))))))))
604
605(defmacro define-setf-expander (name arglist &rest body)
606 "Define a `setf' method.
607This method shows how to handle `setf's to places of the form (NAME ARGS...).
608The argument forms ARGS are bound according to ARGLIST, as if NAME were
609going to be expanded as a macro, then the BODY forms are executed and must
610return a list of five elements: a temporary-variables list, a value-forms
611list, a store-variables list (of length one), a store-form, and an access-
612form. See `gv-define-expander', `gv-define-setter', and `gv-define-expander'
613for a better and simpler ways to define setf-methods."
614 (declare (debug
615 (&define name cl-lambda-list cl-declarations-or-string def-body)))
616 `(progn
617 ,@(if (stringp (car body))
618 (list `(put ',name 'setf-documentation ,(pop body))))
619 (gv-define-expander ,name
620 (cl-function
621 (lambda (do ,@arglist)
622 (cl--gv-adapt (progn ,@body) do))))))
623
624(defmacro defsetf (name arg1 &rest args)
625 "Define a `setf' method.
626This macro is an easy-to-use substitute for `define-setf-expander' that works
627well for simple place forms. In the simple `defsetf' form, `setf's of
628the form (setf (NAME ARGS...) VAL) are transformed to function or macro
629calls of the form (FUNC ARGS... VAL). Example:
630
631 (cl-defsetf aref aset)
632
633Alternate form: (cl-defsetf NAME ARGLIST (STORE) BODY...).
634Here, the above `setf' call is expanded by binding the argument forms ARGS
635according to ARGLIST, binding the value form VAL to STORE, then executing
636BODY, which must return a Lisp form that does the necessary `setf' operation.
637Actually, ARGLIST and STORE may be bound to temporary variables which are
638introduced automatically to preserve proper execution order of the arguments.
639Example:
640
641 (cl-defsetf nth (n x) (v) `(setcar (nthcdr ,n ,x) ,v))
642
643\(fn NAME [FUNC | ARGLIST (STORE) BODY...])"
644 (declare (debug
645 (&define name
646 [&or [symbolp &optional stringp]
647 [cl-lambda-list (symbolp)]]
648 cl-declarations-or-string def-body)))
649 (if (and (listp arg1) (consp args))
650 ;; Like `gv-define-setter' but with `cl-function'.
651 `(gv-define-expander ,name
652 (lambda (do &rest args)
653 (gv--defsetter ',name
654 (cl-function
655 (lambda (,@(car args) ,@arg1) ,@(cdr args)))
656 do args)))
657 `(gv-define-simple-setter ,name ,arg1)))
658
659;; FIXME: CL used to provide a setf method for `apply', but I haven't been able
660;; to find a case where it worked. The code below tries to handle it as well.
661;; (defun cl--setf-apply (form last-witness last)
662;; (cond
663;; ((not (consp form)) form)
664;; ((eq (ignore-errors (car (last form))) last-witness)
665;; `(apply #',(car form) ,@(butlast (cdr form)) ,last))
666;; ((and (memq (car form) '(let let*))
667;; (rassoc (list last-witness) (cadr form)))
668;; (let ((rebind (rassoc (list last-witness) (cadr form))))
669;; `(,(car form) ,(remq rebind (cadr form))
670;; ,@(mapcar (lambda (form) (cl--setf-apply form (car rebind) last))
671;; (cddr form)))))
672;; (t (mapcar (lambda (form) (cl--setf-apply form last-witness last)) form))))
673;; (gv-define-setter apply (val fun &rest args)
674;; (pcase fun (`#',(and (pred symbolp) f) (setq fun f))
675;; (_ (error "First arg to apply in setf is not #'SYM: %S" fun)))
676;; (let* ((butlast (butlast args))
677;; (last (car (last args)))
678;; (last-witness (make-symbol "--cl-tailarg--"))
679;; (setter (macroexpand `(setf (,fun ,@butlast ,last-witness) ,val)
680;; macroexpand-all-environment)))
681;; (cl--setf-apply setter last-witness last)))
682
683
684;; FIXME: CL used to provide get-setf-method, which was used by some
685;; setf-expanders, but now that we use gv.el, it is a lot more difficult
686;; and in general impossible to provide get-setf-method. Hopefully, it
687;; won't be needed. If needed, we'll have to do something nasty along the
688;; lines of
689;; (defun get-setf-method (place &optional env)
690;; (let* ((witness (list 'cl-gsm))
691;; (expansion (gv-letplace (getter setter) place
692;; `(,witness ,getter ,(funcall setter witness)))))
693;; ...find "let prefix" of expansion, extract getter and setter from
694;; ...the rest, and build the 5-tuple))
695(make-obsolete 'get-setf-method 'gv-letplace "24.2")
696
697(defmacro define-modify-macro (name arglist func &optional doc)
698 "Define a `setf'-like modify macro.
699If NAME is called, it combines its PLACE argument with the other arguments
700from ARGLIST using FUNC: (define-modify-macro incf (&optional (n 1)) +)"
701 (declare (debug
702 (&define name cl-lambda-list ;; should exclude &key
703 symbolp &optional stringp)))
704 (if (memq '&key arglist)
705 (error "&key not allowed in define-modify-macro"))
706 (let ((place (make-symbol "--cl-place--")))
707 `(cl-defmacro ,name (,place ,@arglist)
708 ,doc
709 (,(if (memq '&rest arglist) #'cl-list* #'list)
710 #'cl-callf ',func ,place
711 ,@(cl--arglist-args arglist)))))
712
713;;; Additional compatibility code.
6fa6c4ae
SM
714;; For names that were clean but really aren't needed any more.
715
de7e2b36
SM
716(define-obsolete-function-alias 'cl-macroexpand 'macroexpand "24.2")
717(define-obsolete-variable-alias 'cl-macro-environment
718 'macroexpand-all-environment "24.2")
719(define-obsolete-function-alias 'cl-macroexpand-all 'macroexpand-all "24.2")
6fa6c4ae
SM
720
721;;; Hash tables.
722;; This is just kept for compatibility with code byte-compiled by Emacs-20.
723
724;; No idea if this might still be needed.
725(defun cl-not-hash-table (x &optional y &rest z)
2ee3d7f0 726 (declare (obsolete nil "24.2"))
6fa6c4ae
SM
727 (signal 'wrong-type-argument (list 'cl-hash-table-p (or y x))))
728
729(defvar cl-builtin-gethash (symbol-function 'gethash))
de7e2b36 730(make-obsolete-variable 'cl-builtin-gethash nil "24.2")
6fa6c4ae 731(defvar cl-builtin-remhash (symbol-function 'remhash))
de7e2b36 732(make-obsolete-variable 'cl-builtin-remhash nil "24.2")
6fa6c4ae 733(defvar cl-builtin-clrhash (symbol-function 'clrhash))
de7e2b36 734(make-obsolete-variable 'cl-builtin-clrhash nil "24.2")
6fa6c4ae
SM
735(defvar cl-builtin-maphash (symbol-function 'maphash))
736
de7e2b36
SM
737(make-obsolete-variable 'cl-builtin-maphash nil "24.2")
738(define-obsolete-function-alias 'cl-map-keymap 'map-keymap "24.2")
739(define-obsolete-function-alias 'cl-copy-tree 'copy-tree "24.2")
740(define-obsolete-function-alias 'cl-gethash 'gethash "24.2")
741(define-obsolete-function-alias 'cl-puthash 'puthash "24.2")
742(define-obsolete-function-alias 'cl-remhash 'remhash "24.2")
743(define-obsolete-function-alias 'cl-clrhash 'clrhash "24.2")
744(define-obsolete-function-alias 'cl-maphash 'maphash "24.2")
745(define-obsolete-function-alias 'cl-make-hash-table 'make-hash-table "24.2")
746(define-obsolete-function-alias 'cl-hash-table-p 'hash-table-p "24.2")
747(define-obsolete-function-alias 'cl-hash-table-count 'hash-table-count "24.2")
6fa6c4ae 748
bb3faf5b
SM
749(defun cl-maclisp-member (item list)
750 (declare (obsolete member "24.2"))
751 (while (and list (not (equal item (car list)))) (setq list (cdr list)))
752 list)
753
2ee3d7f0
SM
754;; Used in the expansion of the old `defstruct'.
755(defun cl-struct-setf-expander (x name accessor pred-form pos)
756 (declare (obsolete nil "24.2"))
757 (let* ((temp (make-symbol "--cl-x--")) (store (make-symbol "--cl-store--")))
758 (list (list temp) (list x) (list store)
759 `(progn
760 ,@(and pred-form
761 (list `(or ,(cl-subst temp 'cl-x pred-form)
762 (error ,(format
763 "%s storing a non-%s"
764 accessor name)))))
765 ,(if (eq (car (get name 'cl-struct-type)) 'vector)
766 `(aset ,temp ,pos ,store)
767 `(setcar
768 ,(if (<= pos 5)
769 (let ((xx temp))
770 (while (>= (setq pos (1- pos)) 0)
771 (setq xx `(cdr ,xx)))
772 xx)
773 `(nthcdr ,pos ,temp))
774 ,store)))
775 (list accessor temp))))
776
de7e2b36 777;; FIXME: More candidates: define-modify-macro, define-setf-expander.
6fa6c4ae 778
7467c796 779(provide 'cl)
fcd73769 780;;; cl.el ends here