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 a
before, if already set, bind it to t
locally. otherwise, it doesn't matter a
.
source to share
The code fails: (wrong-type-argument symbolp (if (boundp (quote a)) (quote a) (quote dummy)))
by indicating that the special form let
* 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 a
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 a
originally unbound, you would need to assign a
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 let
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