Mercurial > hg > xemacs-beta
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 |