4

Q: How can I test (programmatically) whether a variable has been defined, but not initialized?

(defvar foo)

EXAMPLE:

(if (my-test foo)
  (message "%s has been defined, but not initialized." foo)
  (message "%s has been defined AND initialized." foo))
1
  • 1
    The problem is that, at the lowest level of LISP, just mentioning a variable (technically an atom in LISP) makes it exist. To ask the question of whether it exists, you have to mention it, so the answer is always Yes. The defvar does do a bit more that just make the variable exist, but I'm not sure any of that would be good enough. If you don't care about that distinction, you could use boundp which just tests if there's a value.
    – MAP
    Commented Jan 18, 2017 at 18:27

1 Answer 1

6

The following works only with lexical binding, because with dynamic binding (defvar foo) has no real effect. It checks whether let-binding the variable affects the dynamic value or not. I used the term "declared" instead of "defined", because (defvar foo) doesn't quite feel like a full definition to me (e.g., it only applies to the file it's in) so it's more like C's "declare".

;; -*- lexical-binding: t -*-

(defvar foo 2)
(defvar bar)

(defmacro check-var (var)
  `(message "%s %s"
            ',var
            (cond ((boundp ',var) "has been initialized")
                  ((let ((,var t)) (boundp ',var))
                   "has been declared, but not initialized")
                  (t "has NOT been declared nor initialized"))))

(check-var foo)
(check-var bar)
(check-var qux)

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.