5

What is the difference between the two functions func1 and func2?

(defun func1 (arg)
  (if (listp arg)
      (mapcar (lambda (x) (func1 x)) arg)
    arg))

(func1 (list 1 2 3))

(defun func2 (arg)
  (if (listp arg)
      (mapcar func2 arg)
    arg))

(func2 (list 1 2 3))

func1 works fine, but func2 throws void-variable func2. Why?

1 Answer 1

11
+100

Short Answer

Replace func2 with #'func2:

(defun func2 (arg)
  (if (listp arg)
      (mapcar #'func2 arg)
    arg))

Explanation

Emacs Lisp is a lisp-2 (like Common Lisp), not lisp-1 (unlike, say, Scheme).

I.e., every symbol in ELisp has a

  • "value cell": accessed by symbol-value, tested by boundp, and used by the compiler when the symbol is in the "variable" position, i.e., not as the first element of a list to be evaluated - like your use of func2.
  • "function cell": accessed by symbol-function, tested by fboundp, and used by the compiler when the symbol is in the "function" position, i.e., the first element of a list to be evaluated - like your use of func1.

Since func2 is in variable position and it has a function binding and not a variable binding, you are getting the void variable error. You need to tell the compiler to use the function value instead of the variable value, and this is accomplished by prefixing it with #' (you can use the ordinary quote ' instead too, but it is a bad idea because it makes code less readable and self-documenting).

See also Why use #' before function arguments in emacs-lisp?

4
  • 1
    Note that sharp-quoting is not required and a regular quote will do fine.
    – wasamasa
    Nov 28, 2016 at 18:26
  • 3
    @wasamasa: yes you can, but no you should NOT. code readability matters!
    – sds
    Nov 28, 2016 at 18:51
  • @sds But the Emacs manual does not do it either: mapcar
    – ceving
    Oct 25, 2021 at 9:09
  • @ceving: this is a hold-over from ancient times; please report it as a bug.
    – sds
    Oct 25, 2021 at 12:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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