sbcl Common Lisp incf警告

水猫

我正在关注有关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的正确方法是什么?

tfb

确实,这就是您要增加的方式x,或者至少是这样做的一种方式。但是,这并不是您要绑定的方式x在CL中,您需要先使用名称建立绑定,然后再使用它,而不仅仅是通过分配它来实现。因此,例如,此代码(在新的CL图像中)不是合法的CL:

(defun bad ()
  (setf y 2))

通常,这可能会导致编译时警告和运行时错误,尽管它可能还会执行其他操作:未定义其行为。

尤其是,您所做的实际上比这更糟:您将一个值添加到symbol-valueof中x(使用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)))

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从Common Lisp / SBCL压缩更多速度

来自分类Dev

Common Lisp(SBCL)中的动态变量关闭

来自分类Dev

如何使用SBCL正确保存Common Lisp图像?

来自分类Dev

Common Lisp / SLIME / SBCL的安装例程是什么?

来自分类Dev

在sb-ext:run-program中,如何在sbcl(common-lisp)中使用参数?

来自分类Dev

是否可以在运行时在SBCL / Common Lisp中检查/获取函数类型或其签名?

来自分类Dev

如何使用SBCL Common Lisp从文件加载非标准字符?

来自分类Dev

Lisp SBCL宏引用列表作为参数

来自分类Dev

奇怪的常见Lisp错误(SBCL)

来自分类Dev

嵌套的`defun`在Allegro Common Lisp中产生重复警告

来自分类Dev

(组成)在Common Lisp中

来自分类Dev

Jupyter和Common Lisp

来自分类Dev

Common Lisp中的'()vs()

来自分类Dev

#ifndef在Common Lisp中

来自分类Dev

〜|的含义 以Common Lisp格式

来自分类Dev

如何在通用Lisp(SBCL)中执行execve()?

来自分类Dev

如何在sbcl(或通用lisp)的向量中指定元素类型?

来自分类Dev

如何在Lisp(sbcl)中查看函数的定义?

来自分类Dev

常见的Lisp sbcl手册ffi示例失败

来自分类Dev

如何说服Lisp SBCL进行内联fixnum算法?

来自分类Dev

sbcl(目录“ *”)未返回所有文件(例如,缺少* .lisp)

来自分类Dev

如何在sbcl(或通用lisp)的向量中指定元素类型?

来自分类Dev

如何在通用Lisp(SBCL)中执行execve()?

来自分类Dev

Common Lisp中的功能范围

来自分类Dev

使用Common Lisp读取文件

来自分类Dev

如何构建Common Lisp项目?

来自分类Dev

使用Common Lisp Apache fastcgi

来自分类Dev

将此翻译为Common Lisp

来自分类Dev

Common Lisp:#+ nil是什么?

Related 相关文章

热门标签

归档