2016-10-18 29 views
1

我下面就口齿不清的教程和他们做了下面的代码SBCL Common Lisp的INCF警告

(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的正确方法?

回答

1

这的确是你的意思是增加x,或者至少有一种方式。然而,这不是你如何绑定x。在CL中,您需要在使用它之前为名称建立一个绑定,而您不需要通过分配给它。所以,举例来说,这个代码(在一个新的CL图像)是不合法的CL:

(defun bad() 
    (setf y 2)) 

通常,这会导致编译时警告和运行时错误,虽然它可以做别的事情:其行为没有定义。

你做了什么,特别是,其实比这更糟糕的:你已经撞向一个值的xsymbol-value(与set,它做到这一点),然后假定像(incf x)会的工作,它是极不可能做到。例如考虑这样的事情:

(defun worse() 
    (let ((x 2)) 
    (set 'x 4) 
    (incf x) 
    (values x (symbol-value 'x)))) 

这是(不像bad)法人代码,但它可能是你想要它做的事情没有做。

许多CL实现允许分配给先前未绑定的变量在顶层,因为在会话环境中它很方便。但这些作业的确切含义超出了语言标准。

CMUCL及其衍生产品(包括SBCL)在历史上对此比其他实施更为严肃。我认为原因是解释者比其他人更加严肃,并且/或者他们秘密地编译了所有的东西,编译器挑选了一些东西。

的另一个问题是,CL有顶层变量略显尴尬的语义:如果你去建立一个顶层以正常的方式结合的努力,与defvar &朋友,那么你也引起变量是特殊的 - 动态范围 - 这是一个普遍的影响:它使所有该名称的绑定特殊。这往往是一个非常不受欢迎的后果。 CL作为一种语言,没有顶级词汇变量的概念。因此,有多少实现做了什么,因此,有什么样的顶级绑定的非形式化的概念并不意味着一个特殊的声明:如果你只是在最顶层说(setf x 3),那么这不会使整个环境。但后来出现了各种尴尬的问题:在这样做之后,例如(symbol-value 'x)的结果是什么?

幸运的是CL是一种功能强大的语言,它很有可能在定义语言中的顶级词法变量。这是一个非常冒险的实现,名为deflexical。请注意,有更好的实现(包括我至少有一个,我现在找不到):这并不意味着是一个防弹解决方案。

(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))) 
+0

看起来行我需要更多的阅读。你能建议一个好的来源吗? – Hydrocat

+0

@Hydrocat:我不是一个真正合适的人:当我学习CL时,实际上只有CLtL(虽然是一本有趣的书)并不是真正的好的当前信息的来源。我喜欢保罗格雷厄姆的书籍,我认为这些书籍现在是免费的,而且这个规范不适合学习。也许别人有更好的和更近期的想法。 – tfb

+0

哦,很好:)我其实有一本格雷厄姆的书。那么我应该在好手中! – Hydrocat