0
(defmacro ek/bind-evil-keys-map (state keymap key-fn-list)
  (let* ((key-fns (symbol-value key-fn-list))
       (body (mapcar
              (lambda (pair)
                `(evil-define-key ,state ,keymap (kbd ,(car pair)) ,(cdr pair)))
              key-fns)))
  `(progn ,@body))
)

(defvar motion-keys
  '(
    ("C-o" . 'ek/xref-go-back)
    ("<C-i>" . 'ek/xref-go-forward)
    ))

(ek/bind-evil-keys-map '(normal motion) 'global motion-keys)

Here I'm using symbol-value,
I read macro doesn't evaluate arguments (but function does) so, I tried (eval key-fn-list).

But it seems it is not same as (symbol-value key-fn-list).
So what is the difference?

Drew
  • 75,699
  • 9
  • 109
  • 225
eugene
  • 481
  • 1
  • 5
  • 11
  • 1
    FWIW, you should not `eval` / `symbol-value` a symbol coming from a macro form during macro-expansion. (Actually you can, but you may get unexpected results.) – shynur Sep 01 '23 at 08:38

2 Answers2

2

(Here I don't discuss the reasonableness of OP evaluating a symbol from a macro form during macro-expansion.
 You have your own idea, either way, I can't stop you from doing it.)

You should always use symbol-value when possible.
GNU Emacs Lisp Reference Manual, 10.5 Eval:

Often eval is not needed and something else should be used instead. For example, to get the value of a variable, while eval works, symbol-value is preferable;

Avoid using eval when possible.
See also “A mutable object stops being mutable if it is part of an expression that is evaluated.”.
GNU Emacs Lisp Reference Manual, 2.9 Mutability:

A mutable object stops being mutable if it is part of an expression that is evaluated. For example:

(let* ((x (list 0.5))
       (y (eval (list 'quote x))))
  (setcar x 1.5) ;; The program should not do this.
  y)

Although the list (0.5) was mutable when it was created, it should not have been changed via setcar because it was given to eval.

shynur
  • 4,065
  • 1
  • 3
  • 23
1

If you need to evaluate the arguments, then you shouldn’t be writing a macro. Just write this as an ordinary function.

To answer your question, simply use C-h f to look up the help for both eval and symbol-value. You will soon see the difference; eval evaluates arbitrary code, while symbol-value takes a symbol and returns the value of the variable named by that symbol.

Edit:

I checked the documentation of evil-define-key (I don’t use evil-mode myself), and I have no idea why you are writing this macro. evil-define-key already lets you bind an arbitrary number of keys. Your code could just be written like this:

(evil-define-key '(normal insert) global-map
    "C-o"   'ek/xref-go-back
    "<C-i>" 'ek/xref-go-forward)

You really should read the documentation of these things using C-h i. It will save you a lot of wasted work.

db48x
  • 15,741
  • 1
  • 19
  • 23
  • I read function evaluates the argument (whereas macro doesnt) , here `evaluate` is not the same as `eval` ? is it actually `symbol-value` ? – eugene Sep 01 '23 at 06:01
  • I tried to not use macro so hard (because it was so hard to use it for the first time) but I couldn't make a function that can take a symbol and forward it to a macro here (evil-define-key is the macro) – eugene Sep 01 '23 at 06:05
  • 1
    “Evaluate” _always_ means `eval`. If `eval` sees a symbol, it will call `symbol-value`. If it sees `(+ 2 2)`, it will call `(apply #'+ 2 2)`, and so on. – db48x Sep 01 '23 at 12:09