I don't understand why I get (void-variable test-map) when trying to run:

(defun something--key-map (name)
  (make-symbol (concat (symbol-name name) "-map")))

(defmacro defsomething (name)
     (defvar ,(something--key-map name) (make-sparse-keymap))
     (message "key map %s" ,(something--key-map name))))

(defsomething test)

When I try to (macroexpand '(defsomething test)) I get (progn (defvar test-map (make-sparse-keymap)) (message "key map %s" test-map)), which when I paste it to scratch buffer, it is working. Do you know why it is not working directly?

  • emacs.stackexchange.com/questions/39351 might be useful too.
    – phils
    Commented May 6, 2023 at 23:41
  • Is it good idea to do those changes, if anybody in the future will have same problem as me, defvar would not work in his macro, he will never find this question and answer to it and in previous comment is already link to question that directly asks about source of this problem. Would not it be better to revert those changes, what do you think? @shynur
    – tino415
    Commented May 7, 2023 at 7:40
  • previous comment fyi @Drew
    – tino415
    Commented May 7, 2023 at 7:40
  • @tino415: You're right. I thought extracting the crux (Symbols With a Same Name Are Not Equal) of this question is better, but such a question already exists, so it's a good idea to edit it in order to make it more specific.
    – shynur
    Commented May 7, 2023 at 8:57

1 Answer 1

Update (important)

To recognize uninterned symbols easily, set print-gensym:

(defmacro mac ()
  (let ((a (make-symbol "taffy"))
        (b (make-symbol "taffy")))
    `(eq ',a ',b)))

(macroexpand '(mac))
;; => (eq 'taffy 'taffy)

(let ((print-gensym t))
  (macroexpand '(mac)))
;; => (eq '#:taffy '#:taffy)

C-h f make-symbol:

Return a newly allocated uninterned symbol whose name is NAME.
Its value is void, and its function definition and property list are nil.


(let ((a (make-symbol "taffy"))
      (b (make-symbol "taffy")))
  (eq a b))
;; => nil


Your defvared test-map is not the same symbol as the test-map you passed to message. Emacs allocates memory for them separately, thus of course not eq.

And the latter's value is void since it isn't defvared.

You didn't ask how to implement what you want, but I guess you want to know.

Replace make-symbol with intern. (C-h f intern for details.)

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.