0

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.

1 Answers1

1

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))
Steve Vinoski
  • 19,847
  • 3
  • 31
  • 46
  • But`(lambda (acc v) (and acc v))` only takes two arguments. How can I generalize this for any number of arguments, as with `and`? – Philippe-André Lorin Sep 01 '23 at 14:28
  • 1
    It doesn't need to be generalized because in the context of `seq-reduce`, the function is called with only two arguments: the first argument is either the initial value (for the first call) or the accumulated value (for all subsequent calls), and the second argument is the next element of the sequence. Even if you could pass `and` directly, `seq-reduce` would only ever call it with two arguments. – Steve Vinoski Sep 01 '23 at 14:48