1

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?

  • 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). – Basil Jun 22 at 9:30
  • Ah of course. Thanks! – Tohiko Jun 22 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. – Drew Jun 22 at 14:45
  • I have a feeling this question is a dup. I suggest searching for void-function... and maybe tag [debugging]. – Drew Jun 22 at 14:48
  • @Drew I'm also pretty sure it's a duplicate but I can't find the original. – Basil Jun 22 at 15:05
2

Emacs is a “Lisp-2”: functions and values have separate namespaces. 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.

To call a function which is stored in the value slot of a symbol, use funcall.

(funcall fn x)

More generally, but infrequently, the argument to funcall can be any Lisp expression. funcall is an ordinary function.

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)))))
| improve this answer | |

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.