sbcl通用Lisp incf警告
我在学习lisp教程,他们编写了以下代码sbcl通用Lisp incf警告,lisp,increment,sbcl,Lisp,Increment,Sbcl,我在学习lisp教程,他们编写了以下代码 (set 'x 11) (incf x 10) 翻译给出了以下错误: ; in: INCF X ; (SETQ X #:NEW671) ; ; caught WARNING: ; undefined variable: X ; ; compilation unit finished ; Undefined variable: ; X ; caught 1 WARNING condition 21 增加x的正确方法是什
(set 'x 11)
(incf x 10)
翻译给出了以下错误:
; in: INCF X
; (SETQ X #:NEW671)
;
; caught WARNING:
; undefined variable: X
;
; compilation unit finished
; Undefined variable:
; X
; caught 1 WARNING condition
21
增加x的正确方法是什么?这确实是增加x的方法,或者至少是一种方法。但是,这并不是您要绑定
x
的方式。在CL中,您需要在使用名称之前为其建立绑定,而不仅仅是为其赋值。因此,例如,此代码(在新CL图像中)不是合法CL:
(defun bad ()
(setf y 2))
通常,这将导致编译时警告和运行时错误,尽管它可能会执行其他操作:其行为未定义
特别是,您所做的事情实际上比这更糟糕:您将一个值插入到x
的符号值中(使用set
,它会这样做),然后假设像(incf x)
这样的东西会起作用,这是极不可能做到的。例如,考虑这样的事情:
(defun worse ()
(let ((x 2))
(set 'x 4)
(incf x)
(values x (symbol-value 'x))))
这是(不同于糟糕的)法律代码,但它可能不符合您的要求
许多CL实现确实允许在顶层分配到以前未绑定的变量,因为在对话环境中这很方便。但这些作业的确切含义并不符合语言标准
CMUCL及其衍生产品,包括SBCL,在历史上比当时的其他实现更重视这一点。我认为这是因为解释器比其他大多数解释器更严肃,或者他们秘密地编译了所有的东西,而编译器会把东西捡起来
另一个问题是CL对于顶级变量的语义有点笨拙:如果您使用defvar
&friends以正常方式建立顶级绑定,那么您也会导致变量是特殊的——动态范围——这是一种普遍的效果:它使该名称的所有绑定都是特殊的。这通常是一个非常不受欢迎的结果。CL作为一种语言,没有顶级词汇变量的概念
因此,许多实现所做的是有某种非正式的概念,即某事物的顶级绑定,这并不意味着一个特殊的声明:如果您只是在顶层说(setf x 3)
,那么这不会影响整个环境。但随后出现了各种各样的尴尬问题:在这样做之后,(符号值'x)
的结果是什么
幸运的是,CL是一种功能强大的语言,在该语言中定义顶级词汇变量是完全可能的。这是一个非常粗糙的实现,名为defflexical
。请注意,还有更好的实现(包括我自己的至少一个,我现在找不到):这不是一个防弹解决方案
(defmacro deflexical (var &optional value)
;; Define a cheap-and-nasty global lexical variable. In this
;; implementation, global lexicals are not boundp and the global
;; lexical value is not stored in the symbol-value of the symbol.
;;
;; This implementation is *not* properly thought-through and is
;; without question problematic
`(progn
(define-symbol-macro ,var (get ',var 'lexical-value))
(let ((flag (cons nil nil)))
;; assign a value only if there is not one already, like DEFVAR
(when (eq (get ',var 'lexical-value flag) flag)
(setf (get ',var 'lexical-value) ,value))
;; Return the symbol
',var)))
看来我需要更多的阅读。你能推荐一个好的信息来源吗?@Hydrocat:我真的不是合适的人选:当我学习CL时,实际上只有CLtL(虽然是一本有趣的书),它并不是一个好的、最新的信息来源。我喜欢保罗·格雷厄姆(Paul Graham)的书,我认为这本书现在是免费的,而说明书也不好学。也许其他人有更好的、更新的想法。哦,很好:)我实际上得到了一本格雷厄姆的书。那我就应该有好帮手了!