Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs Lisp map over a list of function names and call them all with the same arg

Tags:

lisp

elisp

I'm having trouble understanding the approach I need to take to fold over a list of functions and invoke them all with a particular argument.

Here is what I as assumed would work. I've tried various variations on it, using eval etc. Any pointers?

(mapcar (lambda (fn) (fn 'utf-8))
        (list #'set-terminal-coding-system
              #'set-keyboard-coding-system
              #'prefer-coding-system))

When I run this I just get "Symbol's function definition is void: fn".

EDIT | Ok, so this works, but it seems odd to need to use apply when the above example passes the functions with the #'function-name synax.

(mapcar (lambda (fn) (apply fn '(utf-8)))
        '(set-terminal-coding-system
          set-keyboard-coding-system
          prefer-coding-system))
like image 218
d11wtq Avatar asked Feb 16 '23 12:02

d11wtq


1 Answers

In Emacs lisp, symbols have separate value and function slots1.

Function arguments are passed in as the value of the argument's symbol, but when you evaluate (fn 'utf-8) you are using the fn symbol's function slot, which will not contain what you want (or in this instance, anything at all; hence the error "Symbol's function definition is void: fn").

To call a function held in a variable, you must therefore funcall or apply (or similar).

See also:

  • In elisp, how do I put a function in a variable?
  • C-hig (elisp) Calling Functions RET
  • C-hig (elisp) Function Names RET

1 i.e. it is a so-called "lisp-2", as opposed to a "lisp-1" where there is a single name-space for both.

like image 67
phils Avatar answered May 19 '23 21:05

phils