lisp,赋值函数的差异

标签 lisp common-lisp

我是 lisp 的新手,所以很抱歉这个问题可能很简单,

虽然我了解 DEFVAR 和 DEFPARAMETER 之间的区别(defvar 仅设置 undefined variable ),并且 LET 仅适用于本地范围,但与前面提到的其他赋值函数相比,SETF 的用途是什么?

最佳答案

DEFVAR 和 DEFPARAMETER 定义和设置全局特殊(动态绑定(bind))变量。

SETF 和 SETQ 设置变量(全局或局部、特殊或词法),但不定义它们。

SETF 比 SETQ 有更多的功能,因为它可以设置“位置”(例如列表中的元素、数组、对象的槽...)。

编辑:

Paul 说在 CLISP 中 SETF 定义了变量。这不完全是它的作用。让我们来看看:

我们有以下程序:

(defun foo (a)
  (setf baz (* a a))
  a)

(defun bar (a)
  (setf baz (* a a))
  a)

现在让我们看看如果我们编译该程序,CLISP 会说什么:

[1]> (compile-file "/tmp/test.lisp")
;; Compiling file /tmp/test.lisp ...
WARNING in FOO in lines 2..4 :
BAZ is neither declared nor bound,
it will be treated as if it were declared SPECIAL.
WARNING in BAR in lines 6..8 :
BAZ is neither declared nor bound,
it will be treated as if it were declared SPECIAL.
;; Wrote file /tmp/test.fas
0 errors, 2 warnings

在这两个函数中,CLISP 都警告我们变量 BAZ 既未声明也未绑定(bind)。 CLISP 没有拒绝代码,而是将变量 BAZ 视为特殊声明。

如果我们加载并运行代码,情况会改变吗?

[1]> (load "/tmp/test")
;; Loading file /tmp/test.fas ...
;; Loaded file /tmp/test.fas
T
[2]> (foo 2)
2
[3]> (bar 3)
3
[4]> baz
9
[5]> (compile-file "/tmp/test.lisp")
;; Compiling file /tmp/test.lisp ...
WARNING in FOO in lines 2..4 :
BAZ is neither declared nor bound,
it will be treated as if it were declared SPECIAL.
WARNING in BAR in lines 6..8 :
BAZ is neither declared nor bound,
it will be treated as if it were declared SPECIAL.

不,即使在执行了 SETF 语句之后,CLISP 仍认为变量 BAZ 未声明。

SBCL 编译器是这样说的:

; in: DEFUN BAR
;     (SETF BAZ (* A A))
; ==>
;   (SETQ BAZ (* A A))
;
; caught WARNING:
;   undefined variable: BAZ

; in: DEFUN FOO
;     (SETF BAZ (* A A))
; ==>
;   (SETQ BAZ (* A A))
;
; caught WARNING:
;   undefined variable: BAZ

LispWorks 编译器是这样说的:

;;;*** Warning in FOO: BAZ assumed special in SETQ
; FOO
;;;*** Warning in BAR: BAZ assumed special in SETQ
; BAR

关于lisp,赋值函数的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2664333/

相关文章:

common-lisp - Common Lisp : where is default test for MEMBER, FIND 和 POSITION 指定?

Emacs:用于自动完成的 ac-slime

lisp - lisp 中一个名为 xtoy 的函数,它返回一个从 x 到 y 的列表

namespaces - “Lisp-1 vs Lisp-2”是否与具有静态类型的语言相关?

clojure - 如何优雅地结合资源和异常处理?

lisp - CCL 保存应用程序,Clisp Saveinitmem,问题

带有蒲公英插件的 Eclipse : Error on Evaluation of LISP Programs on Debian

macros - 评估宏体内传递的参数

lisp - 普通口齿不清 : How to return a list without the nth element of a given list?

macros - 构建评估的评估是否等于宏观?