2

Can someone explain to me why the code below throws an error (void-function fn)?

(let ((lexical-binding t)
      (fn (lambda (y) (+ y 4)))
      (x 4))
  (pcase x
    (10 (- x 2))
    (4 (fn x))))

and is there a way to fix it without defun'ing a function?

And also for the invalid-function error when evaluating an expression to a function:

(setq flist '(+ - * /))
(+ - * /)

(car flist)
+

(functionp (car flist))
t

((car flist) 1 3)
Lisp error: (invalid-function (car flist))
10
  • 4
    let binds variables, not functions. So fn is a variable whose value is a function. You need to call it as (funcall fn x). Commented Jun 22, 2020 at 9:30
  • Ah of course. Thanks! Commented Jun 22, 2020 at 9:36
  • @Basil: Please consider posting that answer as an answer. Comments can be deleted at any time. But maybe check also to see whether the question is a duplicate. Thx. Commented Jun 22, 2020 at 14:45
  • 1
    @Drew I'm also pretty sure it's a duplicate but I can't find the original. Commented Jun 22, 2020 at 15:05
  • 1
    After observing that several of us have struggled at various times to identify a canonical Q&A for the general lisp-1 vs lisp-2 confusion, I've added parts of emacs.stackexchange.com/questions/84875 here to try to make this Q&A cover both cases and be the obvious duplicate in future. Commented Aug 12 at 13:05

1 Answer 1

4

Emacs is a “Lisp-2” where the "2" means that function names and variable names are in two distinct name-spaces, and hence there can be both a function and a variable with any given name foo.

A function definition (defun foo …) and a function call (foo …) use the function slot of the symbol foo. A variable assignment (setq foo …), a variable binding (let ((foo …)) …), and a variable reference x use the value slot of the symbol foo.

A consequence is that we need more than just the syntax (foo …) for calling functions, as we need to distinguish between calling the function named foo, and evaluating the variable foo to a function value and calling that.

In Emacs Lisp (foo …) only ever calls the function by that name. To call a function which is stored in the value slot of a symbol (i.e. a variable), use funcall.

(funcall fn x)

More generally, but infrequently, the argument to funcall can be any Lisp expression.

(funcall (car flist) 1 3)

funcall is an ordinary function, so its arguments are evaluated before the call happens (in these examples meaning that fn and (car flist) are each evaluated to their function values).

Note also that the error invalid function (caar flist) was not saying that (caar flist) doesn't evaluate to a function, but rather that the form (caar flist) itself is not a function (it's a list of two symbols).

Lisp functions take a list of arguments. Sometimes, in addition to calling a variable function, you need to call the function with a variable list of arguments. In this case, use apply instead of funcall. The last argument to apply is used as a list of remaining arguments.

In this particular case, where the code of the function is fully known, you can also use cl-flet from the CL library that is distributed with Emacs. This doesn't let you easily pass the function around, which may or may not be an issue in your real program.

(require 'cl-lib)
(let ((lexical-binding t)
      (x 4))
  (cl-flet ((fn (y) (+ y 4)))
    (pcase x
      (10 (- x 2))
      (4 (fn x)))))

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.