Common Lisp:检查词法变量是否存在?

时间:2016-06-05 15:53:20

标签: scope common-lisp

如何检测范围内是否绑定了词法变量?我基本上想要boundp作为词汇变量。

具体来说,我说:

(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.")))

因此boundp正确检查动态变量(和常量),而as the hyperspec says不包括词法绑定。

但是我找不到任何等同于boundp的词法绑定。那我该怎么检查呢? (如果没有任何可移植的话,SBCL的实现特定代码就可以了。)

2 个答案:

答案 0 :(得分:7)

ANSI Common Lisp中没有类似的东西。无法访问词汇环境。

你只能这样检查:

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>

没有办法取一个名字,看它是否有词汇限制。 CL有一个扩展,其中函数variable-information会提供一些信息,但即使在这种情况下它也可能不起作用:

* (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

答案 1 :(得分:1)

对于cltl2:变量信息可以工作,它应该在宏扩展时间内完成。

(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