[alexandria-devel] Re: length=1
Tobias C. Rittweiler
tcr at freebits.de
Sat Feb 23 10:52:47 UTC 2008
"Attila Lendvai" <attila.lendvai at 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))
, at 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)))))
More information about the alexandria-devel
mailing list