1 ;;; cl.el --- Compatibility aliases for the old CL library. -*- lexical-binding: t -*-
3 ;; Copyright (C) 2012 Free Software Foundation, Inc.
5 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
6 ;; Keywords: extensions
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
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.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25 ;; This is a compatibility file which provides the old names provided by CL
26 ;; before we cleaned up its namespace usage.
33 ;; (defun cl--rename ()
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)
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"))
54 ;; (t (error "Unknown type %S" type))))))))
55 ;; (let ((re (concat "\\_<" (regexp-opt (append vdefs fdefs)) "\\_>"))
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-\\&"))
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)))
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))
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)))
86 ;;; Aliases to cl-lib's features.
97 ;; lambda-list-keywords
98 float-negative-epsilon
100 least-negative-normalized-float
101 least-positive-normalized-float
106 ;; custom-print-functions
108 (defvaralias var
(intern (format "cl-%s" var
))))
112 (random* . cl-random
)
116 (truncate* . cl-truncate
)
117 (ceiling* . cl-ceiling
)
119 (rassoc* . cl-rassoc
)
121 (member* . cl-member
)
122 (delete* . cl-delete
)
123 (remove* . cl-remove
)
124 (defsubst* . cl-defsubst
)
126 (function* . cl-function
)
127 (defmacro* . cl-defmacro
)
129 (mapcar* . cl-mapcar
)
208 define-compiler-macro
222 (define-setf-method . define-setf-expander
)
310 (let ((new (if (consp fun
) (prog1 (cdr fun
) (setq fun
(car fun
)))
311 (intern (format "cl-%s" fun
)))))
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
)
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
)
323 ;;; Features provided a bit differently in Elisp.
325 ;; First, the old lexical-let is now better served by `lexical-binding', tho
326 ;; it's not 100% compatible.
328 (defvar cl-closure-vars nil
)
329 (defvar cl--function-convert-cache nil
)
331 (defun cl--function-convert (f)
332 "Special macro-expander for special cases of (function F).
333 The 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'."
337 (declare-function cl--expr-contains-any
"cl-macs" (x y
))
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
))
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
))
360 #'(lambda ,(append new
(cadr f
))
361 ,@(cl-sublis sub body
)))
362 ,@(nconc (mapcar (lambda (x) `(list 'quote
,x
))
364 '((quote --cl-rest--
))))))
365 (let* ((newf `(lambda ,(cadr f
) ,@body
))
366 (res `(function ,newf
)))
367 (setq cl--function-convert-cache
(cons newf res
))
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
))
378 (defmacro lexical-let
(bindings &rest body
)
379 "Like `let', but lexically scoped.
380 The main visible difference is that lambdas inside BODY will create
381 lexical 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
387 (or (consp x
) (setq x
(list x
)))
388 (push (make-symbol (format "--cl-%s--" (car x
)))
390 (set (car cl-closure-vars
) [bad-lexical-ref
])
391 (list (car x
) (cadr x
) (car cl-closure-vars
))))
397 `(,(car x
) (symbol-value ,(cl-caddr x
))))
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...).
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)
417 `(let ,(mapcar (lambda (x)
419 `(make-symbol ,(format "--%s--" (car x
)))))
421 (setf ,@(apply #'append
423 (list `(symbol-value ,(cl-caddr x
)) (cadr x
)))
427 (defmacro lexical-let
* (bindings &rest body
)
428 "Like `let*', but lexically scoped.
429 The main visible difference is that lambdas inside BODY, and in
430 successive bindings within BINDINGS, will create lexical closures
431 as in Common Lisp. This is similar to the behavior of `let*' in
433 \n(fn BINDINGS BODY)"
434 (declare (indent 1) (debug let
))
435 (if (null bindings
) (cons 'progn body
)
436 (setq bindings
(reverse bindings
))
438 (setq body
(list `(lexical-let (,(pop bindings
)) ,@body
))))
441 ;; This should really have some way to shadow 'byte-compile properties, etc.
442 (defmacro flet
(bindings &rest body
)
443 "Make temporary overriding function definitions.
444 This is an analogue of a dynamically scoped `let' that operates on the function
445 cell of FUNCs rather than their value cell.
446 If you want the Common-Lisp style of `flet', you should use `cl-flet'.
447 The FORMs are evaluated with the specified function definitions in place,
448 then the definitions are undone (the FUNCs go back to their previous
449 definitions, or lack thereof).
451 \(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
452 (declare (indent 1) (debug cl-flet
)
453 (obsolete "use either `cl-flet' or `cl-letf'." "24.3"))
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
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' \
467 will not work - use `labels' instead" (symbol-name (car x
))))
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
)))
477 (defmacro labels
(bindings &rest body
)
478 "Make temporary function bindings.
479 Like `cl-labels' except that the lexical scoping is handled via `lexical-let'
480 rather than relying on `lexical-binding'."
481 (declare (indent 1) (debug cl-flet
) (obsolete cl-labels
"24.3"))
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
)))))
488 (push `(cl-function (lambda .
,(cdr binding
))) sets
)
490 (push (cons (car binding
)
491 `(lambda (&rest cl-labels-args
)
492 (cl-list* 'funcall
',var
495 (macroexpand-all `(lexical-let ,vars
(setq ,@sets
) ,@body
) newenv
)))
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
499 ;; still need to support old users of cl.el.
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
)))
510 (defmacro letf
(bindings &rest body
)
511 "Dynamically scoped let-style bindings for places.
512 For more details, see `cl-letf'. This macro behaves like that one
513 in almost every respect (apart from details that relate to some
514 deprecated usage of `symbol-function' in place forms)." ; bug#12760
515 (declare (indent 1) (debug cl-letf
))
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
))
523 (defun cl--gv-adapt (cl-gv do
)
524 ;; This function is used by all .elc files that use define-setf-expander and
525 ;; were compiled with Emacs>=24.3.
526 (let ((vars (nth 0 cl-gv
))
530 ;; Use cl-sublis as was done in cl-setf-do-modify.
532 (if (macroexp-copyable-p (car vals
))
533 (push (cons (pop vars
) (pop vals
)) substs
)
534 (push (list (pop vars
) (pop vals
)) 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)).
541 (macroexp-let2 macroexp-copyable-p v exp
542 (cl-sublis (cons (cons (car (nth 2 cl-gv
)) v
)
546 (defmacro define-setf-expander
(name arglist
&rest body
)
547 "Define a `setf' method.
548 This method shows how to handle `setf's to places of the form
549 \(NAME ARGS...). The argument forms ARGS are bound according to
550 ARGLIST, as if NAME were going to be expanded as a macro, then
551 the BODY forms are executed and must return a list of five elements:
552 a temporary-variables list, a value-forms list, a store-variables list
553 \(of length one), a store-form, and an access- form.
555 See `gv-define-expander', and `gv-define-setter' for better and
556 simpler ways to define setf-methods."
558 (&define name cl-lambda-list cl-declarations-or-string def-body
)))
560 ,@(if (stringp (car body
))
561 (list `(put ',name
'setf-documentation
,(pop body
))))
562 (gv-define-expander ,name
564 (lambda (do ,@arglist
)
565 (cl--gv-adapt (progn ,@body
) do
))))))
567 (defmacro defsetf
(name arg1
&rest args
)
568 "Define a `setf' method.
569 This macro is an easy-to-use substitute for `define-setf-expander'
570 that works well for simple place forms.
572 In the simple `defsetf' form, `setf's of the form (setf (NAME
573 ARGS...) VAL) are transformed to function or macro calls of the
574 form (FUNC ARGS... VAL). For example:
578 You can replace this form with `gv-define-simple-setter'.
580 Alternate form: (defsetf NAME ARGLIST (STORE) BODY...).
582 Here, the above `setf' call is expanded by binding the argument
583 forms ARGS according to ARGLIST, binding the value form VAL to
584 STORE, then executing BODY, which must return a Lisp form that
585 does the necessary `setf' operation. Actually, ARGLIST and STORE
586 may be bound to temporary variables which are introduced
587 automatically to preserve proper execution order of the arguments.
590 (defsetf nth (n x) (v) `(setcar (nthcdr ,n ,x) ,v))
592 You can replace this form with `gv-define-setter'.
594 \(fn NAME [FUNC | ARGLIST (STORE) BODY...])"
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
606 (lambda (,@(car args
) ,@arg1
) ,@(cdr args
)))
608 `(gv-define-simple-setter ,name
,arg1
,(car args
))))
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)
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))
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)))
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
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))
646 (make-obsolete 'get-setf-method
'gv-letplace
"24.3")
648 (defmacro define-modify-macro
(name arglist func
&optional doc
)
649 "Define a `setf'-like modify macro.
650 If NAME is called, it combines its PLACE argument with the other
651 arguments from ARGLIST using FUNC. For example:
653 (define-modify-macro incf (&optional (n 1)) +)
655 You can replace this macro with `gv-letplace'."
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
)
664 (,(if (memq '&rest arglist
) #'cl-list
* #'list
)
665 #'cl-callf
',func
,place
666 ,@(cl--arglist-args arglist
)))))
668 ;;; Additional compatibility code.
669 ;; For names that were clean but really aren't needed any more.
671 (define-obsolete-function-alias 'cl-macroexpand
'macroexpand
"24.3")
672 (define-obsolete-variable-alias 'cl-macro-environment
673 'macroexpand-all-environment
"24.3")
674 (define-obsolete-function-alias 'cl-macroexpand-all
'macroexpand-all
"24.3")
677 ;; This is just kept for compatibility with code byte-compiled by Emacs-20.
679 ;; No idea if this might still be needed.
680 (defun cl-not-hash-table (x &optional y
&rest _z
)
681 (declare (obsolete nil
"24.3"))
682 (signal 'wrong-type-argument
(list 'cl-hash-table-p
(or y x
))))
684 (defvar cl-builtin-gethash
(symbol-function 'gethash
))
685 (make-obsolete-variable 'cl-builtin-gethash nil
"24.3")
686 (defvar cl-builtin-remhash
(symbol-function 'remhash
))
687 (make-obsolete-variable 'cl-builtin-remhash nil
"24.3")
688 (defvar cl-builtin-clrhash
(symbol-function 'clrhash
))
689 (make-obsolete-variable 'cl-builtin-clrhash nil
"24.3")
690 (defvar cl-builtin-maphash
(symbol-function 'maphash
))
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")
704 (define-obsolete-function-alias 'cl-map-keymap-recursively
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")
709 (defun cl-maclisp-member (item list
)
710 (declare (obsolete member
"24.3"))
711 (while (and list
(not (equal item
(car list
)))) (setq list
(cdr list
)))
714 ;; Used in the expansion of the old `defstruct'.
715 (defun cl-struct-setf-expander (x name accessor pred-form pos
)
716 (declare (obsolete nil
"24.3"))
717 (let* ((temp (make-symbol "--cl-x--")) (store (make-symbol "--cl-store--")))
718 (list (list temp
) (list x
) (list store
)
721 (list `(or ,(cl-subst temp
'cl-x pred-form
)
723 "%s storing a non-%s"
725 ,(if (eq (car (get name
'cl-struct-type
)) 'vector
)
726 `(aset ,temp
,pos
,store
)
730 (while (>= (setq pos
(1- pos
)) 0)
731 (setq xx
`(cdr ,xx
)))
733 `(nthcdr ,pos
,temp
))
735 (list accessor temp
))))