Table of Contents
There are two built-in libraries for Common-Lisp-like functions in Emacs Lisp:
cl-lib.el. The former is sort of obsolete and defines lots of functions without
cl- prefix. The latter defines lots of functions with
cl- prefix. For example, Emacs Lisp
mapcar takes only one sequence, Common Lisp
mapcar can take many sequences, and that is implemented as
cl.el, and as
cl-lib.el. I will refer to functions like
mapcar* defined in
cl.el as old style CL functions, and functions like
cl-mapcar as new style CL functions or CL-LIB functions.
Some old style CL functions are now aliases for new style CL functions. Some old style functions may be explicitly obsolete and their CL-LIB analogs may work differently.
When you use CL-LIB functions in some code, others reading that code know that it needs
(require 'cl-lib) to work. When you use old style CL functions in some code, others copying the code may end up seeing error because you forgot to say that the code needs
(require 'cl) to work. It is easy for you to forget this because it is hard to know whether a given part of code requires cl or not just from just reading it, unless you have memorized the names of all old style CL functions, or unless you have set up your Emacs so that it highlights names of old style CL functions.
2 highlighting old style CL function names
You can put the following code to your init file to have emacs-lisp-mode highlight all occurrences of old style CL functions with flyspell-incorrect face. I am using that face so that the face says “hey, this is an old style CL function. you must correct this by using new style function instead.” to me. Others may prefer different kind of face that says “hey, you used an old style CL function. nothing wrong with that, but let me highlight this so that you can easily see that this piece of code requires cl”
(defconst my-old-style-cl-functions '(acons adjoin assert assoc* assoc-if assoc-if-not block caaaar caaadr caaar caadar caaddr caadr cadaar cadadr cadar caddar cadddr caddr callf callf2 case cdaaar cdaadr cdaar cdadar cdaddr cdadr cddaar cddadr cddar cdddar cddddr cdddr ceiling* check-type coerce compiler-macroexpand concatenate copy-list copy-seq count count-if count-if-not decf declaim define-compiler-macro define-modify-macro define-setf-expander define-setf-method defmacro* defsetf defstruct defsubst* deftype defun* delete* delete-duplicates delete-if delete-if-not destructuring-bind do do* do-all-symbols do-symbols ecase eighth endp equalp etypecase eval-when evenp every fifth fill find find-if find-if-not first flet floatp-safe floor* fourth function* gcd gensym gentemp get* getf incf intersection isqrt labels lcm ldiff letf letf* lexical-let lexical-let* list* list-length load-time-value locally loop macrolet make-random-state map mapcan mapcar* mapcon mapl maplist member* member-if member-if-not merge minusp mismatch mod* multiple-value-apply multiple-value-bind multiple-value-call multiple-value-list multiple-value-setq nintersection ninth notany notevery nreconc nset-difference nset-exclusive-or nsublis nsubst nsubst-if nsubst-if-not nsubstitute nsubstitute-if nsubstitute-if-not nth-value nunion oddp pairlis plusp position position-if position-if-not proclaim progv psetf psetq pushnew random* random-state-p rassoc* rassoc-if rassoc-if-not reduce rem* remf remove* remove-duplicates remove-if remove-if-not remprop replace rest return return-from revappend rotatef round* search second set-difference set-exclusive-or seventh shiftf signum sixth some sort* stable-sort sublis subseq subsetp subst subst-if subst-if-not substitute substitute-if substitute-if-not svref symbol-macrolet tailp tenth the third tree-equal truncate* typecase typep union values values-list)) (defconst my-rx-old-style-cl-functions (eval `(rx bow (or ,@(mapcar #'symbol-name my-old-style-cl-functions)) eow))) (eval-after-load 'lisp-mode '(progn (require 'flyspell) ; for the flyspell-incorrect face (font-lock-add-keywords 'emacs-lisp-mode `((,my-rx-old-style-cl-functions . 'flyspell-incorrect)))))
3 some anomalies
There are three Emacs Lisp functions which can be used without loading cl, but are redefined as old style CL functions when you load cl. These are
dotimes. The code I gave you does not highlight them.
4 how I got the list
I got the list of old style CL function names by running the following code from
(defvar all-functions nil) (mapatoms (lambda (sym) (if (fboundp sym) (push sym all-functions)))) (require 'cl) (defvar all-obs nil) (mapatoms (lambda (sym) (if (and (fboundp sym) (not (memq sym all-functions)) (let* ((def (symbol-function sym)) (filename (find-lisp-object-file-name sym def))) (and (not (string-match-p (rx bos "cl-") (symbol-name sym))) (string-match-p (rx "cl.el" eos) filename)))) (push sym all-obs)))) (print (sort all-obs #'string<))