Search code examples
emacslisp-macros

Substitute symbol name in macro


How can I substitute a symbol name into a function created in a macro? I think I am missing something obvious here. For example, I am trying to make a macro that defines some variables and functions similar to the following,

(cl-defmacro mac (pkg)
  (let (
        ;; Define some variables
        (sym (intern (concat pkg "-file")))
        (sym-def "default-file.el")
        (sym-doc (concat "A custom var from `" pkg "'."))
        ;; Define some functions
        (symfn (intern (concat pkg "-fn")))
        (symfn-doc (concat "A function for `" pkg "'.")))

    `(list
      (defcustom ,sym ,sym-def ,sym-doc
        :group (quote ,(make-symbol pkg))
        :type '(choice (const :tag "None" nil)
                       file))
      (defun ,symfn ()
        ,symfn-doc
        (interactive)
        (fn ,sym)))))

The function returned makes a call out to another function (fn) with a signature like

(defun fn (var) (symbol-value var))

So, it is expecting a call like (fn 'some-var). And, I want to be able to use the macro like

(mac "pack")

And have the following work,

pack-file  ; works: "default-file.el"
(pack-fn)  ; error: not a symbol

I have tried things like (quote ,sym), symbol-name, and others... But can't seem to get it right.


Solution

  • You want the call to fn to be (fn ',sym) (which you mention you tried in the question, but I suspect got wrong somehow).

    You probably also want the expansion of the macro to be (progn ...) instead of (list ...).

    (This was originally a comment: I'm putting it here just so there's an answer.)