0

I would like to add an alternative answer to the thread How do I force re-evaluation of a defvar? Before doing so, however, I would like to learn how to eliminate the single-quote to prevent evaluation of the argument INPUT to the new function defvar-reevaluate. Perhaps I need a macro instead of a function ....?

BEFORE:

(defun defvar-reevaluate (input)
"Force revelaution of a defvar."
  (let* ((string (prin1-to-string input))
         (form (read string))
         (form (elisp--eval-defun-1 (macroexpand form))))
    (eval form)))

(defvar-reevaluate
  '(defvar undo-auto--this-command-amalgamating "hello-world"
  "My new doc-string"))

AFTER -- without the single quote.

(defvar-reevaluate
  (defvar undo-auto--this-command-amalgamating "hello-world"
  "My new doc-string"))
1

If you want to pass a non-evaluated expression as argument without quote you have to use a macro since the arguments of (non-special) functions are evaluated before the function call.

(quote a) evaluates just to the un-evaluated expression expr. That's why (quote expr) works as argument.

Your code with the defun replaced by defmacro could look like the following demo.

(defmacro defvar-reevaluate (input)
  "Force revelaution of a defvar."
  (let* ((string (prin1-to-string input))
     (form (read string))
     (form (eval-sexp-add-defvars (elisp--eval-defun-1 (macroexpand form)))))
    form))

(defvar-reevaluate
  (defvar undo-auto--this-command-amalgamating "hello-world"
    "My new doc-string"))

Note that the last eval from your defun is not required since the returned expression of the macro is evaluated at the call of defvar-reevaluate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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