-(defun find-if (predicate sequence &key (key #'identity))
- (do-sequence (x sequence)
- (when (funcall predicate (funcall key x))
- (return x))))
-
-(defun some (function seq)
- (do-sequence (elt seq)
- (when (funcall function elt)
- (return-from some t))))
-
-(defun every (function seq)
- (do-sequence (elt seq)
- (unless (funcall function elt)
- (return-from every nil)))
- t)
-
-(defun position (elt sequence)
- (let ((pos 0))
- (do-sequence (x seq)
- (when (eq elt x)
- (return))
- (incf pos))
- pos))
-
-
-(defun remove (x seq)
+(defun position (elt sequence
+ &key key (test #'eql testp)
+ (test-not #'eql test-not-p)
+ (start 0) end)
+ ;; TODO: Implement START and END efficiently for all the sequence
+ ;; functions.
+ (let ((end (or end (length sequence))))
+ (do-sequence (x sequence index)
+ (when (and (<= start index)
+ (< index end)
+ (satisfies-test-p elt x
+ :key key :test test :testp testp
+ :test-not test-not :test-not-p test-not-p))
+ (return index)))))
+
+;; TODO: need to support &key from-end
+(defun position-if (predicate sequence
+ &key key (start 0) end)
+ ;; TODO: Implement START and END efficiently for all the sequence
+ ;; functions.
+ (let ((end (or end (length sequence))))
+ (do-sequence (x sequence index)
+ (when (and (<= start index)
+ (< index end)
+ (funcall predicate (if key (funcall key x) x)))
+ (return index)))))
+
+(defun position-if-not (predicate sequence
+ &key key (start 0) end)
+ (position-if (complement predicate) sequence :key key :start start :end end))
+
+(defun remove (x seq &key key (test #'eql testp) (test-not #'eql test-not-p))