Elisp: boundp in let
How can I check for a variable defined before or not within the let construct?
(let (((if (boundp 'a) 'a 'dummy) t)) (message "I made this work"))
What I am trying to do is check if the constraint is constrained
before, if already set, bind it to
locally. otherwise, it doesn't matter
source to share
The code fails:
(wrong-type-argument symbolp (if (boundp (quote a)) (quote a) (quote dummy)))
by indicating that the special form
* does not evaluate this argument (although this list will evaluate to a symbol, the list itself is not a symbol).
Here is a simple but flawed alternative approach that creates a local binding for
whatever, but then unbinds it in that local scope if it was originally disabled.
(let ((a (if (boundp 'a) t nil))) (or a (makunbound 'a)) ;; do things )
The downside is that if
originally unbound, you would need to assign
inside that local scope in order to survive the local scope, and that won't be the case with this approach.
At first I thought that you have to give up completely
to get around this issue, and just use something like this:
(when (boundp 'a) (setq a-backup a a t)) ;; do things (when (boundp 'a-backup) (setq a a-backup) (makunbound 'a-backup))
Then I realized that, as with many other things, macros are the answer:
(defmacro let-if-bound (var value &rest body) "Bind variable VAR to VALUE only if VAR is already bound." (declare (indent 2)) `(if (boundp ',var) (let ((,var ,value)) ,@body) (progn ,@body))) (let-if-bound a t ;; do things )
(*) "Special form" is a primitive function that is specially marked so that not all of its arguments are evaluated. Most of the special forms define structure control or perform variable bindings - things they cannot do.
Each special form has its own rules for which arguments are evaluated and which are used without evaluation. Whether a particular argument is scored may depend on the scoring results of other arguments.
source to share