1 ;;; cl-lib.el --- Properly prefixed CL functions and macros -*- coding: utf-8 -*-
3 ;; Copyright (C) 2012, 2013, 2014 Free Software Foundation, Inc.
5 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
6 ;; vcomment: Emacs-24.3's version is 1.0 so this has to stay below.
9 ;; This program is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
14 ;; This program is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
24 ;; This is a forward compatibility package, which provides (a subset of) the
25 ;; features of the cl-lib package introduced in Emacs-24.3, for use on
28 ;; Make sure this is installed *late* in your `load-path`, i.e. after Emacs's
29 ;; built-in .../lisp/emacs-lisp directory, so that if/when you upgrade to
30 ;; Emacs-24.3, the built-in version of the file will take precedence, otherwise
31 ;; you could get into trouble (although we try to hack our way around the
32 ;; problem in case it happens).
34 ;; This code is largely copied from Emacs-24.3's cl.el, with the alias bindings
39 (when (functionp 'macroexp--compiler-macro)
40 ;; `macroexp--compiler-macro' was introduced as part of the big CL
41 ;; reorganization which moved/reimplemented some of CL into core (mostly the
42 ;; setf and compiler-macro support), so its presence indicates we're running
43 ;; in an Emacs that comes with the new cl-lib.el, where this file should
45 (message "Real cl-lib shadowed by compatibility cl-lib? (%s)" load-file-name)
47 ;; (message "Let's try to patch things up")
48 (let ((loaddir (file-name-directory load-file-name))
50 ;; Find the problematic directory from load-path.
51 (dolist (dir load-path)
52 (if (equal loaddir (expand-file-name (file-name-as-directory dir)))
53 (setq load-path-dir dir)))
55 ;; (message "Let's move the offending dir to the end")
56 (setq load-path (append (remove load-path-dir load-path)
57 (list load-path-dir)))
58 ;; Here we could manually load cl-lib and then return immediately.
59 ;; But Emacs currently doesn't provide any way for a file to "return
60 ;; immediately", so instead we make sure the rest of the file does not
61 ;; throw away any pre-existing definition.
66 ;; Some of Emacs-24.3's cl.el definition are not just aliases, because either
67 ;; the feature was dropped from cl-lib.el or because the cl-lib version is
68 ;; not fully compatible.
69 ;; Let's just not include them here, since it is very important that if code
70 ;; works with this cl-lib.el it should also work with Emacs-24.3's cl-lib.el,
71 ;; whereas the reverse is much less important.
82 ;; lambda-list-keywords
83 float-negative-epsilon
85 least-negative-normalized-float
86 least-positive-normalized-float
91 ;; custom-print-functions
93 (let ((new (intern (format "cl-%s" var))))
94 (unless (boundp new) (defvaralias new var))))
96 ;; The following cl-lib functions were already defined in the old cl.el,
97 ;; with a different meaning:
98 ;; - cl-position and cl-delete-duplicates
99 ;; the two meanings are clearly different, but we can distinguish which was
100 ;; meant by looking at the arguments.
102 ;; the old meaning hasn't been used for a long time and is a subset of the
103 ;; new, so we can simply override it.
105 ;; the old meaning is actually the same as the new except for optimizations.
109 (random* . cl-random)
113 (truncate* . cl-truncate)
114 (ceiling* . cl-ceiling)
116 (rassoc* . cl-rassoc)
118 ;; (member* . cl-member) ;Handle specially below.
119 (delete* . cl-delete)
120 (remove* . cl-remove)
121 (defsubst* . cl-defsubst)
123 (function* . cl-function)
124 (defmacro* . cl-defmacro)
126 (mapcar* . cl-mapcar)
185 ;; position ;Handle specially via defadvice below.
195 ;; delete-duplicates ;Handle specially via defadvice below.
205 define-compiler-macro
250 ;; adjoin ;It's already defined.
312 (let ((new (if (consp fun) (prog1 (cdr fun) (setq fun (car fun)))
313 (intern (format "cl-%s" fun)))))
315 (unless (or (eq (symbol-function new) fun)
316 (eq new (and (symbolp fun) (fboundp fun)
317 (symbol-function fun))))
318 (message "%S already defined, not rebinding" new))
319 (defalias new fun))))
321 (autoload 'cl-position "cl-seq")
322 (defadvice cl-position (around cl-lib (cl-item cl-seq &rest cl-keys) activate)
323 (let ((argk (ad-get-args 2)))
324 (if (or (null argk) (keywordp (car argk)))
325 ;; This is a call to cl-lib's `cl-position'.
326 (setq ad-return-value
327 (apply #'position (ad-get-arg 0) (ad-get-arg 1) argk))
328 ;; Must be a call to cl's old `cl-position'.
331 (autoload 'cl-delete-duplicates "cl-seq")
332 (defadvice cl-delete-duplicates (around cl-lib (cl-seq &rest cl-keys) activate)
333 (let ((argk (ad-get-args 1)))
334 (if (or (null argk) (keywordp (car argk)))
335 ;; This is a call to cl-lib's `cl-delete-duplicates'.
336 (setq ad-return-value
337 (apply #'delete-duplicates (ad-get-arg 0) argk))
338 ;; Must be a call to cl's old `cl-delete-duplicates'.
341 (when (or (not (fboundp 'cl-member))
342 (eq (symbol-function 'cl-member) #'memq))
343 (defalias 'cl-member #'member*))
345 ;; `cl-labels' is not 100% compatible with `labels' when using dynamic scoping
346 ;; (mostly because it does not turn lambdas that refer to those functions into
347 ;; closures). OTOH it is compatible when using lexical scoping.
349 (unless (fboundp 'cl-labels)
350 (defmacro cl-labels (&rest args)
351 (unless (and (boundp 'lexical-binding) lexical-binding)
352 ;; We used to signal an error rather than a message, but in many uses of
353 ;; cl-labels, the value of lexical-binding doesn't actually matter.
354 ;; More importantly, the value of `lexical-binding' here is unreliable
355 ;; (it does not necessarily reflect faithfully whether the output of this
356 ;; macro will be interpreted as lexically bound code or not).
357 (message "This `cl-labels' requires `lexical-binding' to be non-nil"))
362 ;; 2014-01-25 Stefan Monnier <monnier@iro.umontreal.ca>
364 ;; * cl-lib.el: Resolve conflicts with old internal definitions
366 ;; (dolist fun): Don't skip definitions silently.
367 ;; (define-setf-expander): Remove, not in cl-lib.
368 ;; (cl-position, cl-delete-duplicates): Add advice to distinguish the use
370 ;; (cl-member): Override old definition.
372 ;; 2013-05-22 Stefan Monnier <monnier@iro.umontreal.ca>
374 ;; * cl-lib.el (cl-labels): Demote error to message and improve it.
376 ;; 2012-11-30 Stefan Monnier <monnier@iro.umontreal.ca>
378 ;; * cl-lib.el: Try and patch things up in case we're hiding the real
381 ;; 2012-11-22 Stefan Monnier <monnier@iro.umontreal.ca>
383 ;; Add cl-letf and cl-labels.
385 ;; 2012-11-16 Stefan Monnier <monnier@iro.umontreal.ca>
387 ;; * packages/cl-lib: New package.
392 ;;; cl-lib.el ends here