help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [External] : Re: Testing whether a list contains at least one non-ni


From: Drew Adams
Subject: RE: [External] : Re: Testing whether a list contains at least one non-nil element
Date: Thu, 27 Oct 2022 03:54:37 +0000

> (defun list-has-non-nil-p (list)
>   "Test if list has non nil element."
>   (elt (remq nil list) 0))

`remq' can end up needlessly traversing and
copying quite a lot of the argument LIST.

(defun remq (elt list)
  (while (and (eq elt (car list))
    (setq list (cdr list))))

  ;; Hey, we're done already.  Empty list
  ;; means no non-nil elements.  Nonempty
  ;; means the car is non-nil.
  ;;
  ;; Why do the rest of this?
  ;; Search for a nil, after the non-nil car?
  ;; Then copy the entire list.  Then delete
  ;; all nils from it?  Why on earth do this?
  (if (memq elt list)
       ^^^^
      (delq elt (copy-sequence list))
                 ^^^^^^^^^^^^^
       ^^^^^^^^^
    list))

First that removes all nils from the beginning
of LIST.  OK.  At that point either the list
is empty, and the answer is nil, or the first
list element is non-nil.  Just stop there.

Why go on, with the remainder of the list,
whose car is non-nil, searching for the next
nil?

Why then copy that entire remaining list and
then traverse it to delete all nils from it?

None of that makes sense.  Talk about "bloat"?
You're using the wrong function to do the job.

If you have a tiny list, or one where you
don't expect any non-nil elements before a
long way into the list, then maybe such wasted
effort isn't a concern.  Otherwise, it might
be.  And it's not needed.

Functions others (including I) sent for this
question don't have any of those problems.
They just traverse the list till they find a
non-nil value.  At worst, they traverse the
whole list once.

You certainly don't need to remove all nils
from the list.  If your list is 100,000,000
elements long and the first element is t, why
would you want to copy the entire list and
then remove all the nils from it?  Testing
the first element tells you the answer.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]