Nyquist / XLISP 2.0  -  Contents | Tutorials | Examples | Reference

Lisp FAQ


  1. Why do #'and and #'or not work with apply and funcall?
  2. Where can I find more Lisp FAQs in the Internet?

Why do #'and and #'or not work with apply and funcall?


From http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part3/faq-doc-3.html

The short answer is that and and or are special operators, not functions, while apply and funcall can only be used to invoke functions, not macros and special operators.

The reason why and and or are special operators is because they implement control structure in addition to computing a boolean value. They evaluate their subforms sequentially from left to right, and stop evaluating subforms as soon as the result can be determined. This is referred to as 'short circuiting'. apply and funcall, however, are ordinary functions. Therefore, their arguments are evaluated before they are called. Thus, were apply able to be used with #'and and or, the short-circuiting would be defeated.

Perhaps you don't really care about the short-circuiting, and simply want the functional, boolean interpretation. While this may be a reasonable interpretation of trying to apply and or or, it doesn't generalize to other macros well, so there's no obvious way to have the Lisp system 'do the right thing' when trying to apply macros. The only function associated with a macro is its expander function. This function accepts and returns and form, so it cannot be used to compute the value.

The Common Lisp functions EVERY, SOME and IDENTITY can be used to get the functionality you intend when trying to apply #'and and #'or:

   (apply #'and list)  →  (every #'identity list)
   (apply #'or  list)  →  (some  #'identity list)

Defining and and or as functions using cons and eval:

(defun and-fn (&rest args)
  (eval (cons 'and args)))

(defun or-fn (&rest args)
  (eval (cons 'or args)))

Defining and and or as functions using dolist:

(defun and-fn (&rest args)
  (dolist (x args t)
    (and (not x) (return nil))))

(defun or-fn (&rest args)
  (dolist (x args nil)
    (and x (return t))))
(defun apply* (function args)
  (if (eq (type-of function) 'fsubr)
      (eval (cons function args))
      (apply function args)))


  Back to top


Where can I find more Lisp FAQs in the Internet?


  Back to top


Nyquist / XLISP 2.0  -  Contents | Tutorials | Examples | Reference