I’m making some tedious calls to a bunch of functions, but the parameters will be determined at runtime. I wrote a simple function to keep my code DRY but giving it a name is unnecessary. I don’t use this function anywhere else.
I’m trying to do it the way I would in Scheme, but I get a void-function error:
(let ((do-work (lambda (x y z)
(do-x x)
(do-y y)
;; etc
)))
(cond (test-1 (do-work 'a 'b 'c))
(test-2 (do-work 'i 'j 'k))))
I could stick it all into an apply (e.g., (apply (lambda ...) (cond ...))) but that isn’t very readable. Is there a better way?
Like other lisps (but not Scheme), Emacs Lisp has separate namespaces for variables and functions (i.e. it is a ‘Lisp2’, not a ‘Lisp1’; see Technical Issues of Separation in Function Cells and Value Cells for the origin and meaning of these terms).
You will need to use
funcallorapplyto call a lambda (or other function) that is stored in a variable.Use
funcallif you will always send the same number of arguments. Useapplyif you need to be able to send a variable number of arguments.The internal mechanism is that each symbol has multiple “cells”.
Which cell is used depends on where the symbol is in an evaluated form.
When a symbol is the first element of an evaluated form, its “function” cell is used.
In any other position, its “value” cell is used.
In your code,
do-workhas the function in its value cell.To access it as a function you use
funcallorapply.If it were in the function cell, you could call it directly by using its name as the car of an evaluated form.
You can accomplish this with
fletorlabelsfrom the cl package.