How to use “and” with “seq-reduce” in Elisp?

77 views Asked by At

I’m trying to write something like this:

(setq l '(nil t nil nil))
(seq-reduce 'and l t)

I get this error:

Invalid function: and

My understanding, after a bit of googling, is that this is due to and being a special form. What would be a good way to make this work? Is there a function equivalent to and? Is there some way to make a function out of a special form? I couldn’t find any documentation about this. I tried to write a function that does what and does, but that seems overkill.

2

There are 2 answers

2
Steve Vinoski On BEST ANSWER

The seq-reduce function uses funcall to invoke its function argument, and as shown in the funcall documentation, a special form like and can't be passed to it; calling (funcall 'and t nil) results in an Invalid function: #<subr and> error.

You can make the call to and in a lambda instead:

(let ((l '(nil t nil nil)))
  (seq-reduce (lambda (acc v) (and acc v)) l t))
1
phils On

Is there a function equivalent to and?

There is not and cannot be a function equivalent to and, because functions evaluate all of their arguments before they are called, and that is in conflict with the behaviour of and which must only evaluate as many arguments as necessary to produce its result.

Imagine (and ok-to-delete (delete-it-all)) if and was a function, for instance. In Lisp it's necessary that the likes of and and or do not unnecessarily evaluate all of their arguments, and therefore they cannot be functions.