4

I would like to evaluate a list of booleans like

(nil nil t)

into a single boolean, such that if any element is true, then the expression evaluates to true.

I first looked at the (or) function in elisp, but it does not take a list of booleans as an argument. Instead it requires its arguments to be "un-wrapped" outside of a list. In other words,

(or (nil nil t))

simply evaluates to the entire list (nil nil t) because it treats the it as a single argument. I would like something that instead evaluates exactly to t. - I understand that (nil nil t) is truthy, but that's beside the point.

How can I convert (or (nil nil t)) into just (or nil nil t) or just t?

After some thought, I can think of

(eval (cons 'or '(nil nil t)))

but is there some other more idiomatic way that I'm missing?

Drew
  • 75,699
  • 9
  • 109
  • 225
Linus Arver
  • 152
  • 1
  • 6

2 Answers2

3

If you wanted this for a function you would use apply, but as or is a special form you can't do that. In particular, or only evaluates as many arguments as it needs to.

You could write a macro:

(defmacro or-list (list)
  `(or ,@(eval list)))

(setq mylist '(a b c))

(or-list mylist) then expands to (or a b c)

phils
  • 48,657
  • 3
  • 76
  • 115
  • To help future searches, it should help to note that this answer makes use of backquotes and splicing, as described in https://www.gnu.org/software/emacs/manual/html_node/elisp/Backquote.html. – Linus Arver Jan 13 '21 at 08:40
2

How about this?

(defun or-list (list)
  (cl-some #'identity list))

Here cl-some takes two arguments: a predicate and a list and returns non-nil if the predicate applied to some member of the list is non-nil. In our case, the identity function is a good predicate since we only want to test whether our list members are themselves non-nil.

Fran Burstall
  • 3,665
  • 10
  • 18