1

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)
  `(progn
     (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?

tino415
  • 13
  • 3
  • https://emacs.stackexchange.com/questions/39351 might be useful too. – phils May 06 '23 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 May 07 '23 at 07:40
  • previous comment fyi @Drew – tino415 May 07 '23 at 07: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 May 07 '23 at 08:57

1 Answers1

3
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.

So

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

A:

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.)

shynur
  • 4,065
  • 1
  • 3
  • 23