首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么SBCL抱怨setf?

为什么SBCL抱怨setf?
EN

Stack Overflow用户
提问于 2020-04-28 23:15:19
回答 2查看 771关注 0票数 7

在SBCL中,这将将'bar分配给foo,并附带警告:

代码语言:javascript
复制
* (setf foo 'bar)
; in: SETF FOO
;     (SETF FOO 'BAR)
; ==>
;   (SETQ FOO 'BAR)
; 
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::FOO
; 
; compilation unit finished
;   Undefined variable:
;     FOO
;   caught 1 WARNING condition
BAR
* 

下面是图雷茨基的。我把它输入"7.29.lisp“并保存下来。

代码语言:javascript
复制
(setf database
’((b1 shape brick)
(b1 color green)
(b1 size small)
(b1 supported-by b2)
(b1 supported-by b3)
(b2 shape brick)
(b2 color red)
(b2 size small)
(b2 supports b1)
(b2 left-of b3)
(b3 shape brick)
(b3 color red)
(b3 size small)
(b3 supports b1)
(b3 right-of b2)
(b4 shape pyramid)
(b4 color blue)
(b4 size large)
(b4 supported-by b5)
(b5 shape cube)
(b5 color green)
(b5 size large)
(b5 supports b4)
(b6 shape brick)
(b6 color purple)
(b6 size large)))

因此:

代码语言:javascript
复制
* (load "7.29.lisp")
While evaluating the form starting at line 1, column 0
  of #P"/home/redacted/7.29.lisp":

debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {10005D05B3}>:
  odd number of args to SETF: (SETF DATABASE ’
                                    ((B1 SHAPE BRICK) (B1 COLOR GREEN)
                                     (B1 SIZE SMALL) (B1 SUPPORTED-BY B2)
                                     (B1 SUPPORTED-BY B3) (B2 SHAPE BRICK)
                                     (B2 COLOR RED) (B2 SIZE SMALL)
                                     (B2 SUPPORTS B1) (B2 LEFT-OF B3)
                                     (B3 SHAPE BRICK) (B3 COLOR RED) ...))

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETRY   ] Retry EVAL of current toplevel form.
  1: [CONTINUE] Ignore error and continue loading file "/home/redacted/7.29.lisp".
  2: [ABORT   ] Abort loading file "/home/redacted/7.29.lisp".
  3:            Exit debugger, returning to top level.

(SB-C::EXPLODE-SETQ (SETF DATABASE ’ ((B1 SHAPE BRICK) (B1 COLOR GREEN) (B1 SIZE SMALL) (B1 SUPPORTED-BY B2) (B1 SUPPORTED-BY B3) (B2 SHAPE BRICK) (B2 COLOR RED) (B2 SIZE SMALL) (B2 SUPPORTS B1) (B2 LEFT-OF B3) (B3 SHAPE BRICK) (B3 COLOR RED) ...)) ERROR)
0] 

我需要了解什么才能让SBCL对这些作业感到满意?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-29 00:20:13

我觉得第一次警告很清楚,tbh。在(setf foo 'bar)中,不知道foo引用变量。它没有被lambdalet这样的表单作为词法变量进行本地绑定,也没有被defvardefparameter这样的表单作为一个特殊变量进行全局绑定。如果您希望它以顶级形式出现,您应该编写(defparameter *foo* 'bar) (请注意,常见的lisp约定是将特定变量的名称围在耳罩中)。如果您想在函数的主体内或在有限的范围内执行此操作,则应该执行(let ((foo 'bar)) (do-stuff-with foo))

至于您的第二个问题,除了database是未绑定的事实之外,您还有错误的引号字符。不是ascii单引号,因此被解析为一个符号.编译器认为您的表单为:(setf database |’| ((b1 shape green) ...)),它不是有效的setf表单。要解决这个问题,请了解如何键入字符',以及/或不要将格式化文档中的粘贴代码复制到纯文本文件中。

票数 13
EN

Stack Overflow用户

发布于 2020-04-29 10:37:38

Phoebe's answer总结它的同时,我想提出一些我发现缺失的上下文。

在普通的lisp中,与其他语言(如python)和其他语言(如C)不同,变量初始化和变量赋值之间有区别。

全局变量使用defvardefparameter引入,局部变量使用letlet*lambda等。然而,这不仅仅是全球或本地的问题--参见this question on dynamic vs lexical scoping

一旦通过上述方法引入了变量,就可以使用setf进行赋值。

“儿童健康和健康法”中使用的适当术语如下:

德瓦尔,非参数

defparameterdefvar将名称设置为动态变量。

参考资料:http://clhs.lisp.se/Body/m_defpar.htm

让,让*

letlet*创建新的变量绑定。

除非有相反的特别声明,否则每个绑定都是词法。

参考资料:http://clhs.lisp.se/Body/s_let_l.htm#let

setf

setf将place的值更改为新值。

参考资料:http://clhs.lisp.se/Body/m_setf_.htm

编辑:考虑到@tfb的评论和CLHS。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61491549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档