How do I detect if a lexical variable is bound in a scope? I basically want boundp
for lexical variables.
Concretely, say I have:
(defvar *dynamic* 1)
(defconstant +constant+ 2)
(let ((lexical 3))
(when (boundp '*dynamic*) ; t
(print "*dynamic* bound."))
(when (boundp '+constant+) ; t
(print "+constant+ bound."))
(when (boundp 'lexical) ; nil
(print "lexical bound.")))
So boundp
correctly checks for dynamic variables (and constants), and as the hyperspec says, doesn't cover lexical bindings.
But I can't find any equivalent of boundp
for lexical bindings. So how do I check them then? (Implementation-specific code for say SBCL is fine if there isn't anything portable.)
There is nothing like that in ANSI Common Lisp. There is no access to a lexical environment.
You only can check it this way:
CL-USER 8 > (let ((lexical 3))
(when (ignore-errors lexical)
(print "lexical bound."))
(values))
"lexical bound."
CL-USER 9 > (let ((lexical 3))
(when (ignore-errors lexxxical)
(print "lexical bound."))
(values))
<nothing>
There is no way to take a name and see if it is lexically bound at all. There is an extension to CL, where the function variable-information
would give some information, but even in this case it would probably not work:
* (require "sb-cltl2")
("SB-CLTL2")
* (apropos "variable-information")
VARIABLE-INFORMATION
SB-CLTL2:VARIABLE-INFORMATION (fbound)
* (let ((lexical 3))
(sb-cltl2:variable-information 'lexical))
; in: LET ((LEXICAL 3))
; (LET ((LEXICAL 3))
; (SB-CLTL2:VARIABLE-INFORMATION 'LEXICAL))
;
; caught STYLE-WARNING:
; The variable LEXICAL is defined but never used.
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
NIL
NIL
NIL
for cltl2:variable-information to work, it should be done in macro expansion time.
(ql:quickload :introspect-environment)
(use-package :introspect-environment) ;; also exports cltl2 functions.
(defmacro in-compile-time ((environment) &body body &environment env)
(check-type environment symbol)
(eval `(let ((,environment ,env)) (progn ,@body)))
nil) ; does not affect the expansion
(defun fn ()
(let ((lexical 2))
(in-compile-time (env)
(print (introspect-environment:variable-information 'lexical env))
(print (introspect-environment:variable-information 'lexxxxical env)))))
; compiling (DEFUN FN ...)
:LEXICAL
NIL
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With