comparison lisp/cl-extra.el @ 5219:2d0937dc83cf

Tidying of CL files; make docstrings read better, remove commented-out code 2010-05-30 Aidan Kehoe <kehoea@parhasard.net> * cl.el: Remove extraneous empty lines. Remove the commented-out Lisp implementation of #'last, #'copy-list. Remove #'cl-maclisp-member. (acons, pairlis): Have the argument list reflect the docstring for these functions. * cl-macs.el (defun*): Have the argument list reflect the docstring. Document the syntax of keywords in ARGLIST. (defmacro*): Have the argument list reflect the docstring. Document &body, &whole and &environment. (function*): Have the argument list reflect the docstring. (loop): Have the argument list reflect the docstring. (eval-when, dolist, dotimes, do-symbols, flet, labels, macrolet, symbol-macrolet): Specify the argument list using the arguments: (...) syntax. (define-setf-method, rotatef, defsubst*): Have the argument list reflect the docstring. (letf, letf*): Specify the argument list using the arguments: (...) syntax. (svref, acons, pairlis): Add compiler macros for these functions. * cl-extra.el: Remove the commented-out Lisp implementation of #'equalp. If we want to look at it, it's in version control. (cl-expt): Remove this. The subr #'expt is always available. Call #'cl-float-limits at dump time. Remove the commented-out Lisp implementation of #'subseq. (concatenate): Use (error 'invalid-argument ...) here, if TYPE is not understood. (list-length): Don't manually get the length of a list, call #'length and return nil if the list is circular. * byte-optimize.el (equalp): This needs byte-optimize-binary-predicate as its optimizer, as do the other equality predicates.
author Aidan Kehoe <kehoea@parhasard.net>
date Sun, 30 May 2010 13:27:36 +0100
parents 41262f87eb39
children 7789ae555c45
comparison
equal deleted inserted replaced
5218:ec2ddc82f10d 5219:2d0937dc83cf
48 48
49 ;;; Code: 49 ;;; Code:
50 ;; XEmacs addition 50 ;; XEmacs addition
51 (eval-when-compile 51 (eval-when-compile
52 (require 'obsolete)) 52 (require 'obsolete))
53
54 (or (memq 'cl-19 features)
55 (error "Tried to load `cl-extra' before `cl'!"))
56
57 53
58 ;;; Type coercion. 54 ;;; Type coercion.
59 55
60 (defun coerce (x type) 56 (defun coerce (x type)
61 "Coerce OBJECT to type TYPE. 57 "Coerce OBJECT to type TYPE.
97 ((equal (cdr-safe type) '(character)) 93 ((equal (cdr-safe type) '(character))
98 (coerce x 'string))))) 94 (coerce x 'string)))))
99 ((typep x type) x) 95 ((typep x type) x)
100 (t (error "Can't coerce %s to type %s" x type)))) 96 (t (error "Can't coerce %s to type %s" x type))))
101 97
102 98 ;; XEmacs; #'equalp is in C.
103 ;;;;; Predicates.
104 ;;
105 ;;;; I'd actually prefer not to have this inline, the space
106 ;;;; vs. amount-it's-called trade-off isn't reasonable, but that would
107 ;;;; introduce bytecode problems with the compiler macro in cl-macs.el.
108 ;;(defsubst cl-string-vector-equalp (cl-string cl-vector)
109 ;; "Helper function for `equalp', which see."
110 ;;; (check-argument-type #'stringp cl-string)
111 ;;; (check-argument-type #'vector cl-vector)
112 ;; (let ((cl-i (length cl-string))
113 ;; cl-char cl-other)
114 ;; (when (= cl-i (length cl-vector))
115 ;; (while (and (>= (setq cl-i (1- cl-i)) 0)
116 ;; (or (eq (setq cl-char (aref cl-string cl-i))
117 ;; (setq cl-other (aref cl-vector cl-i)))
118 ;; (and (characterp cl-other) ; Note we want to call this
119 ;; ; as rarely as possible, it
120 ;; ; doesn't have a bytecode.
121 ;; (eq (downcase cl-char) (downcase cl-other))))))
122 ;; (< cl-i 0))))
123 ;;
124 ;;;; See comment on cl-string-vector-equalp above.
125 ;;(defsubst cl-bit-vector-vector-equalp (cl-bit-vector cl-vector)
126 ;; "Helper function for `equalp', which see."
127 ;;; (check-argument-type #'bit-vector-p cl-bit-vector)
128 ;;; (check-argument-type #'vectorp cl-vector)
129 ;; (let ((cl-i (length cl-bit-vector))
130 ;; cl-other)
131 ;; (when (= cl-i (length cl-vector))
132 ;; (while (and (>= (setq cl-i (1- cl-i)) 0)
133 ;; (numberp (setq cl-other (aref cl-vector cl-i)))
134 ;; ;; Differs from clisp here.
135 ;; (= (aref cl-bit-vector cl-i) cl-other)))
136 ;; (< cl-i 0))))
137 ;;
138 ;;;; These two helper functions call equalp recursively, the two above have no
139 ;;;; need to.
140 ;;(defsubst cl-vector-array-equalp (cl-vector cl-array)
141 ;; "Helper function for `equalp', which see."
142 ;;; (check-argument-type #'vector cl-vector)
143 ;;; (check-argument-type #'arrayp cl-array)
144 ;; (let ((cl-i (length cl-vector)))
145 ;; (when (= cl-i (length cl-array))
146 ;; (while (and (>= (setq cl-i (1- cl-i)) 0)
147 ;; (equalp (aref cl-vector cl-i) (aref cl-array cl-i))))
148 ;; (< cl-i 0))))
149 ;;
150 ;;(defsubst cl-hash-table-contents-equalp (cl-hash-table-1 cl-hash-table-2)
151 ;; "Helper function for `equalp', which see."
152 ;; (symbol-macrolet
153 ;; ;; If someone has gone and fished the uninterned symbol out of this
154 ;; ;; function's constants vector, and subsequently stored it as a value
155 ;; ;; in a hash table, it's their own damn fault when
156 ;; ;; `cl-hash-table-contents-equalp' gives the wrong answer.
157 ;; ((equalp-default '#:equalp-default))
158 ;; (loop
159 ;; for x-key being the hash-key in cl-hash-table-1
160 ;; using (hash-value x-value)
161 ;; with y-value = nil
162 ;; always (and (not (eq equalp-default
163 ;; (setq y-value (gethash x-key cl-hash-table-2
164 ;; equalp-default))))
165 ;; (equalp y-value x-value)))))
166 ;;
167 ;;(defun equalp (x y)
168 ;; "Return t if two Lisp objects have similar structures and contents.
169 ;;
170 ;;This is like `equal', except that it accepts numerically equal
171 ;;numbers of different types (float, integer, bignum, bigfloat), and also
172 ;;compares strings and characters case-insensitively.
173 ;;
174 ;;Arrays (that is, strings, bit-vectors, and vectors) of the same length and
175 ;;with contents that are `equalp' are themselves `equalp'.
176 ;;
177 ;;Two hash tables are `equalp' if they have the same test (see
178 ;;`hash-table-test'), if they have the same number of entries, and if, for
179 ;;each entry in one hash table, its key is equivalent to a key in the other
180 ;;hash table using the hash table test, and its value is `equalp' to the other
181 ;;hash table's value for that key."
182 ;; (cond ((eq x y))
183 ;; ((stringp x)
184 ;; (if (stringp y)
185 ;; (eq t (compare-strings x nil nil y nil nil t))
186 ;; (if (vectorp y)
187 ;; (cl-string-vector-equalp x y)
188 ;; ;; bit-vectors and strings are only equalp if they're
189 ;; ;; zero-length:
190 ;; (and (equal "" x) (equal #* y)))))
191 ;; ((numberp x)
192 ;; (and (numberp y) (= x y)))
193 ;; ((consp x)
194 ;; (while (and (consp x) (consp y) (equalp (car x) (car y)))
195 ;; (setq x (cdr x) y (cdr y)))
196 ;; (and (not (consp x)) (equalp x y)))
197 ;; (t
198 ;; ;; From here on, the type tests don't (yet) have bytecodes.
199 ;; (let ((x-type (type-of x)))
200 ;; (cond ((eq 'vector x-type)
201 ;; (if (stringp y)
202 ;; (cl-string-vector-equalp y x)
203 ;; (if (vectorp y)
204 ;; (cl-vector-array-equalp x y)
205 ;; (if (bit-vector-p y)
206 ;; (cl-bit-vector-vector-equalp y x)))))
207 ;; ((eq 'character x-type)
208 ;; (and (characterp y)
209 ;; ;; If the characters are actually identical, the
210 ;; ;; first eq test will have caught them above; we only
211 ;; ;; need to check them case-insensitively here.
212 ;; (eq (downcase x) (downcase y))))
213 ;; ((eq 'hash-table x-type)
214 ;; (and (hash-table-p y)
215 ;; (eq (hash-table-test x) (hash-table-test y))
216 ;; (= (hash-table-count x) (hash-table-count y))
217 ;; (cl-hash-table-contents-equalp x y)))
218 ;; ((eq 'bit-vector x-type)
219 ;; (if (bit-vector-p y)
220 ;; (equal x y)
221 ;; (if (vectorp y)
222 ;; (cl-bit-vector-vector-equalp x y)
223 ;; ;; bit-vectors and strings are only equalp if they're
224 ;; ;; zero-length:
225 ;; (and (equal "" y) (equal #* x)))))
226 ;; (t (equal x y)))))))
227 99
228 ;; XEmacs; #'map, #'mapc, #'mapl, #'maplist, #'mapcon, #'some and #'every 100 ;; XEmacs; #'map, #'mapc, #'mapl, #'maplist, #'mapcon, #'some and #'every
229 ;; are now in C, together with #'map-into, which was never in this file. 101 ;; are now in C, together with #'map-into, which was never in this file.
230 102
231 (defun notany (cl-pred cl-seq &rest cl-rest) 103 (defun notany (cl-pred cl-seq &rest cl-rest)
346 (if (consp (car cl-progv-save)) 218 (if (consp (car cl-progv-save))
347 (set (car (car cl-progv-save)) (cdr (car cl-progv-save))) 219 (set (car (car cl-progv-save)) (cdr (car cl-progv-save)))
348 (makunbound (car cl-progv-save))) 220 (makunbound (car cl-progv-save)))
349 (pop cl-progv-save))) 221 (pop cl-progv-save)))
350 222
351
352 ;;; Numbers. 223 ;;; Numbers.
353 224
354 (defun gcd (&rest args) 225 (defun gcd (&rest args)
355 "Return the greatest common divisor of the arguments." 226 "Return the greatest common divisor of the arguments."
356 (let ((a (abs (or (pop args) 0)))) 227 (let ((a (abs (or (pop args) 0))))
378 g2) 249 g2)
379 (while (< (setq g2 (/ (+ g (/ a g)) 2)) g) 250 (while (< (setq g2 (/ (+ g (/ a g)) 2)) g)
380 (setq g g2)) 251 (setq g g2))
381 g) 252 g)
382 (if (eq a 0) 0 (signal 'arith-error nil)))) 253 (if (eq a 0) 0 (signal 'arith-error nil))))
383
384 ;; XEmacs addition
385 (defun cl-expt (x y)
386 "Return X raised to the power of Y. Works only for integer arguments."
387 (if (<= y 0) (if (= y 0) 1 (if (memq x '(-1 1)) (cl-expt x (- y)) 0))
388 (* (if (= (% y 2) 0) 1 x) (cl-expt (* x x) (/ y 2)))))
389 (or (and (fboundp 'expt) (subrp (symbol-function 'expt)))
390 (defalias 'expt 'cl-expt))
391 254
392 ;; We can't use macrolet in this file; whence the literal macro 255 ;; We can't use macrolet in this file; whence the literal macro
393 ;; definition-and-call: 256 ;; definition-and-call:
394 ((macro . (lambda (&rest symbols) 257 ((macro . (lambda (&rest symbols)
395 "Make some old CL package truncate and round functions available. 258 "Make some old CL package truncate and round functions available.
470 (defun cl-finite-do (func a b) 333 (defun cl-finite-do (func a b)
471 (condition-case nil 334 (condition-case nil
472 (let ((res (funcall func a b))) ; check for IEEE infinity 335 (let ((res (funcall func a b))) ; check for IEEE infinity
473 (and (numberp res) (/= res (/ res 2)) res)) 336 (and (numberp res) (/= res (/ res 2)) res))
474 (arith-error nil))) 337 (arith-error nil)))
475
476 (defvar most-positive-float)
477 (defvar most-negative-float)
478 (defvar least-positive-float)
479 (defvar least-negative-float)
480 (defvar least-positive-normalized-float)
481 (defvar least-negative-normalized-float)
482 (defvar float-epsilon)
483 (defvar float-negative-epsilon)
484 338
485 (defun cl-float-limits () 339 (defun cl-float-limits ()
486 (or most-positive-float (not (numberp '2e1)) 340 (or most-positive-float (not (numberp '2e1))
487 (let ((x '2e0) y z) 341 (let ((x '2e0) y z)
488 ;; Find maximum exponent (first two loops are optimizations) 342 ;; Find maximum exponent (first two loops are optimizations)
514 (setq x '1e0) 368 (setq x '1e0)
515 (while (/= (- '1e0 x) '1e0) (setq x (/ x 2))) 369 (while (/= (- '1e0 x) '1e0) (setq x (/ x 2)))
516 (setq float-negative-epsilon (* x 2)))) 370 (setq float-negative-epsilon (* x 2))))
517 nil) 371 nil)
518 372
373 ;; XEmacs; call cl-float-limits at dump time.
374 (cl-float-limits)
519 375
520 ;;; Sequence functions. 376 ;;; Sequence functions.
521 377
522 ;XEmacs -- our built-in is more powerful. 378 ;; XEmacs; #'subseq is in C.
523 ;(defun subseq (seq start &optional end)
524 ; "Return the subsequence of SEQ from START to END.
525 ;If END is omitted, it defaults to the length of the sequence.
526 ;If START or END is negative, it counts from the end."
527 ; (if (stringp seq) (substring seq start end)
528 ; (let (len)
529 ; (and end (< end 0) (setq end (+ end (setq len (length seq)))))
530 ; (if (< start 0) (setq start (+ start (or len (setq len (length seq))))))
531 ; (cond ((listp seq)
532 ; (if (> start 0) (setq seq (nthcdr start seq)))
533 ; (if end
534 ; (let ((res nil))
535 ; (while (>= (setq end (1- end)) start)
536 ; (push (pop seq) res))
537 ; (nreverse res))
538 ; (copy-sequence seq)))
539 ; (t
540 ; (or end (setq end (or len (length seq))))
541 ; (let ((res (make-vector (max (- end start) 0) nil))
542 ; (i 0))
543 ; (while (< start end)
544 ; (aset res i (aref seq start))
545 ; (setq i (1+ i) start (1+ start)))
546 ; res))))))
547 379
548 (defun concatenate (type &rest seqs) 380 (defun concatenate (type &rest seqs)
549 "Concatenate, into a sequence of type TYPE, the argument SEQUENCES." 381 "Concatenate, into a sequence of type TYPE, the argument SEQUENCES."
550 ;; XEmacs change: use case instead of cond for clarity 382 ;; XEmacs change: use case instead of cond for clarity
551 (case type 383 (case type
552 (vector (apply 'vconcat seqs)) 384 (vector (apply 'vconcat seqs))
553 (string (apply 'concat seqs)) 385 (string (apply 'concat seqs))
554 (list (apply 'append (append seqs '(nil)))) 386 (list (apply 'append (append seqs '(nil))))
555 (t (error "Not a sequence type name: %s" type)))) 387 (t (error 'invalid-argument "Not a sequence type name" type))))
556 388
557 ;;; List functions. 389 ;;; List functions.
558 390
559 (defun revappend (x y) 391 (defun revappend (x y)
560 "Equivalent to (append (reverse X) Y)." 392 "Equivalent to (append (reverse X) Y)."
562 394
563 (defun nreconc (x y) 395 (defun nreconc (x y)
564 "Equivalent to (nconc (nreverse X) Y)." 396 "Equivalent to (nconc (nreverse X) Y)."
565 (nconc (nreverse x) y)) 397 (nconc (nreverse x) y))
566 398
567 (defun list-length (x) 399 (defun list-length (list)
568 "Return the length of a list. Return nil if list is circular." 400 "Return the length of LIST. Return nil if LIST is circular."
569 (let ((n 0) (fast x) (slow x)) 401 (if (listp list)
570 (while (and (cdr fast) (not (and (eq fast slow) (> n 0)))) 402 (condition-case nil (length list) (circular-list))
571 (setq n (+ n 2) fast (cdr (cdr fast)) slow (cdr slow))) 403 ;; Error on not-a-list:
572 (if fast (if (cdr fast) nil (1+ n)) n))) 404 (car list)))
573 405
574 (defun tailp (sublist list) 406 (defun tailp (sublist list)
575 "Return true if SUBLIST is a tail of LIST." 407 "Return true if SUBLIST is a tail of LIST."
576 (while (and (consp list) (not (eq sublist list))) 408 (while (and (consp list) (not (eq sublist list)))
577 (setq list (cdr list))) 409 (setq list (cdr list)))
578 (if (numberp sublist) (equal sublist list) (eq sublist list))) 410 (if (numberp sublist) (equal sublist list) (eq sublist list)))
579 411
580 (defalias 'cl-copy-tree 'copy-tree) 412 (defalias 'cl-copy-tree 'copy-tree)
581
582 413
583 ;;; Property lists. 414 ;;; Property lists.
584 415
585 ;; XEmacs: our `get' groks DEFAULT. 416 ;; XEmacs: our `get' groks DEFAULT.
586 (defalias 'get* 'get) 417 (defalias 'get* 'get)
822 (and (not full) '((block) (eval-when))))) 653 (and (not full) '((block) (eval-when)))))
823 (message "Formatting...") 654 (message "Formatting...")
824 (prog1 (cl-prettyprint form) 655 (prog1 (cl-prettyprint form)
825 (message "")))) 656 (message ""))))
826 657
827
828
829 (run-hooks 'cl-extra-load-hook) 658 (run-hooks 'cl-extra-load-hook)
830 659
831 ;; XEmacs addition 660 ;; XEmacs addition
832 (provide 'cl-extra) 661 (provide 'cl-extra)
833 662