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

.

+3


source to share


2 answers


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.

+5


source


I think the "canonical" way of doing this would be



(let ((bound (boundp 'a))
      (a t))
  (unless bound (makunbound 'a))
  ...blabla...)

      

+1


source







All Articles