Search code examples
lispemacs23

Invalid function warning with a recursive Lisp function


I'm watching these tutorials on Lisp and I've been following along so far. However, when I try to evaluate this function,

(defun tailfact (n &optional (intermediate 1))
  (if (= n 1)
    (return-from tailfact intermediate))
  (tailfact (1 - n) (* n intermediate)))

(tailfact 5)

I get an Invalid function warning (I'm running this in Emacs). Not sure what to make of it, or how to fix it.


Solution

  • You accidentally wrote a space within the 1- (which is a function for subtracting 1 from the given number). Remove that space (that is, use (1- n) instead of (1 - n)) and try again.

    Also, Emacs Lisp doesn't have return-from. Just say intermediate instead of (return-from tailfact intermediate). You do have to move the tailfact call within the if expression though, as the else clause.

    Oh, in my testing, I found another point of difference between Common Lisp and Emacs Lisp: the latter doesn't support a default value for optional arguments, and it always uses nil. So here's one way to port your code to elisp:

    (defun tailfact (n &optional intermediate)
      (let ((intermediate (or intermediate 1)))
        (if (= n 1)
            intermediate
          (tailfact (1- n) (* n intermediate)))))
    

    However, let me be the first to agree with Rainer's comment. If you're learning from Common Lisp resources, you really should be using a Common Lisp implementation. I've heard that SLIME is an awesome Emacs mode for integrating with major CL implementations, including SBCL (which is probably one of the most commonly-used CL implementations).