7

I'm trying to see if all the values in a list are truthy. For some reason, (apply #'and lst) errors with:

Invalid function: and

This also happens when I try (cl-reduce #'and lst).

However, (apply #'max lst) seems to work fine.

Right now, I'm using (eval `(and ,@lst)), but that feels ugly.

  • 1
    and is a special form rather than a function. – Dan Sep 4 '15 at 19:19
  • 2
    You should use a function with the desired behaviour, such as (cl-every 'identity lst) or (-all? 'identity lst). – wasamasa Sep 4 '15 at 19:22
  • @wasama thanks. I'll do that instead. – PythonNut Sep 4 '15 at 19:34
5

This really is only a partial answer (since I can't say why or really provide a workaround for it beyond what you already have).

As per C-h f and

and is a special form in `C source code'.

(and CONDITIONS...)

Eval args until one of them yields nil, then return nil. The remaining args are not evalled at all. If no arg yields nil, return the last arg's value.

[back]

So even though it behaves like a function it isn't one. The same error gets generated by using a macro in the place of and.

  • 6
    It doesn't behave like a function : that it stops evaluating arguments once one of them is nil. (and nil (drop 'bomb)) is safe as long as and is not a function. – YoungFrog Sep 4 '15 at 19:31
2

To add to and summarize what others have said:

(functionp 'and) ; ===> nil

End of story.

From the Elisp manual, node What Is a Function:

You can use the function functionp to test if an object is a function:

-- Function: functionp object This function returns t if OBJECT is any kind of function, i.e., can be passed to funcall. Note that functionp returns t for symbols that are function names, and returns ‘nil’ for special forms.


(Man, I hate the new curly-quoting in the manuals. Makes me replace each of them with ` after pasting from the manual here. Twice as much effort as when the manual (sanely) used `...' instead of ‘...’.)

0

What is a function?

To understand why this happens, we need to know what is a function. When evaluating the lisp form (myfunc arg1 arg2 ...), emacs first checks what myfunc is. If it is a function, emacs evaluates all lisp forms arg1, arg2, etc. then calls the function myfunc with the resulting lisp objects as arguments.

As was noted, and is not a function, it is a special form, thus it can evaluate its arguments as needed. As I gave in a comment earlier, the form (and nil (drop 'bomb)) is safe because (drop 'bomb) is never evaluated.

On the other hand, (apply #'and (list nil (drop 'bomb))) is not safe, because apply is a function, so emacs first evaluates #'and (the result is a symbol), then evaluates (list nil (drop 'bomb)), which is again a function call, so you guess what happens next : nil is evaluated, then (drop 'bomb) is evaluated.

Why does apply complain ?

Trying to use apply on a special form (or a macro) doesn't make sense, because the special form can't possibly have its special behaviour, so it throws an error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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