"Attila Lendvai" attila.lendvai@gmail.com writes:
dear list,
is there any objections against this?
(declaim (inline length=1))
(defun length=1 (sequence) (if (listp sequence) (and sequence (null (rest sequence))) (= 1 (length sequence))))
in optimized code, where type information is available, it drops the type check. and otherwise it works for sequences and is fast for lists.
maybe it could be extended into two functions: length= and length=1, where length= optimizes for lists using nthcdr.
Yes, I favor such an inclusion. I also vote for including a LENGTH>. I've appended the definitions that I use personally below my email.
There's a compiler macro for LENGTH= for when it's called with either 1 or 2, as these are the numeric arguments I've found myself to use most often.
Exporting LENGTH=1 and LENGTH=2 may be debateable, the only use case is the one Andreas Fuchs mentioned, i.e. as arguments to FIND-IF &c.
-T.
(export '(length= length> length=1 length=2))
(defmacro optimizing-length (inline-p &body body) `(locally (declare (optimize speed) (inline length)) ,@body))
(defun length= (seq n) "Test for whether SEQ contains N number of elements. I.e. it's equivalent to (= (LENGTH SEQ) N), but besides being more concise, it may also be more efficiently implemented." (check-type n integer) (typecase seq (list (do ((i n (1- i)) (list seq (cdr list))) ((or (<= i 0) (null list)) (and (zerop i) (null list))))) (simple-vector (optimizing-length (= n (length seq)))) (vector (optimizing-length (= n (length seq)))) (sequence (optimizing-length (= n (length seq))))))
(define-compiler-macro length= (&whole form sequence n) (cond ((eql n 1) `(length=1 ,sequence)) ((eql n 2) `(length=2 ,sequence)) (t form)))
(defun length> (seq n) "Returns non-nil if (> (length LIST) N)." (check-type n integer) (etypecase seq (list (and (>= n 0) (nthcdr n seq) t)) (simple-vector (optimizing-length (> (length seq) n))) (vector (optimizing-length (> (length seq) n))) (sequence (optimizing-length (> (length seq) n)))))
(defun length=1 (sequence) (declare (optimize speed)) (declare (inline length)) (typecase sequence (list (and sequence (null (rest sequence)))) (simple-vector (= 1 (length sequence))) (vector (= 1 (length sequence))) (sequence (= 1 (length sequence)))))
(defun length=2 (sequence) (declare (optimize speed)) (declare (inline length)) (typecase sequence (list (and sequence (cdr sequence) (null (cddr sequence)))) (simple-vector (= 2 (length sequence))) (vector (= 2 (length sequence))) (sequence (= 2 (length sequence)))))