2

I am trying to create a global variable which name is contained in another variable, using defvar:

(let ((var-name "my-test-var"))
  ;;(defvar (intern var-name) "some value")
  (defvar (make-symbol var-name) "some value"))

This gives error:

(wrong-type-argument symbolp (make-symbol var-name))

The following seems to work

(let ((var-name "my-test-var"))
  (let ((var-sym (intern var-name)))
    (setf (symbol-value var-sym) "some value")))

but is it equivalent to using defvar, and how can I add the doc string as in defvar?

Håkon Hægland
  • 3,608
  • 1
  • 20
  • 51

1 Answers1

3

It isn't equivalent. If you test the symbol of a defvar'd variable with special-variable-p you get t, however this is not the case for your code. This bit must be set for the variable to be usable with dynamic binding. There doesn't appear to be a way to set this bit, other than by using special forms like defvar, defalias or the defcustom macro (which expands into defvar).

The standard solution is to use a macro for programmatically defining variables with generated names:

(defmacro my-defvar (name &optional value docstring)
  (let ((symbol (intern name)))
    `(defvar ,symbol ,value ,docstring)))

(my-defvar "foo" 1)
foo ;=> 1
(special-variable-p 'foo) ;=> t
wasamasa
  • 21,803
  • 1
  • 65
  • 97