3
\$\begingroup\$

I have the following function defined in my .emacs to test if a given executable exists within my $PATH. I implemented it with cl-reduce and the code looks really unidiomatic (to me).

(defun executable-in-path-p (executable)
  "Test if EXECUTABLE exists in path."
  (eq t (cl-reduce
         (lambda (path exists)
           (or (file-exists-p (concat (file-name-as-directory path) executable))
               exists))
         exec-path)))

Is there a more concise way to test if a list, mapped with a predicate function, has at least one element equal to t than this?

(eq t
    (cl-reduce
     (lambda (element acc)
       (or (some-check-p element)
           acc))
     some-list))

In Ruby for example I would write:

some_list.any? { |element| some_check(element) }
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

If you already have Common Lisp-derived functions in there, use CL-SOME instead:

(defun executable-in-path-p (executable)
  "Test if EXECUTABLE exists in path."
  (cl-some (lambda (path) (file-exists-p (concat (file-name-as-directory path) executable))) exec-path))

That's of course a little bit different than explicitly checking for t, but you shouldn't be doing that anyway in most cases (everything but nil is already true).

\$\endgroup\$
1
  • \$\begingroup\$ Thanks, that looks really clean. I agree, checking for truthy values feels a lot more idiomatic than checking vor t explicitly. \$\endgroup\$
    – lukad
    Commented Nov 16, 2016 at 9:06
1
\$\begingroup\$

Apply 'file-exists-p on the list of files and check whether true is a member of the result:

(member t (mapcar 'file-exists-p list-of-files))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.