SETF既不终止也不报告错误 [英] SETF neither terminates nor reports an error

查看:57
本文介绍了SETF既不终止也不报告错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个普通的Lisp初学者,遇到了这段代码:

I'm a Common Lisp beginner and came across this piece of code:

(let ((foo (list 42)))
  (setf (rest foo) foo))

REPL似乎只是

推荐答案

什么是 FOO



FOO 最初是一个新列表,(42)。在Lisp中,列表由 cons单元表示,这是可变内存块,每个块包含一个 CAR CDR 插槽。
另一种打印方式是(42。NIL),其中 CAR CDR 在圆点的两侧。也可以如下所示:

What is FOO?

FOO is initially a fresh list, (42). In Lisp, lists are represented by cons cells, blocks of mutable memory containing each a CAR and a CDR slot. Another way to print it is (42 . NIL), where the CAR and CDR are on each side of the dot. This can also be pictured as follows:

  car  cdr
------------
| 42 | NIL |
------------
     ^
     |
    FOO

当您呼叫 SETF (rest foo) place foo 值,则表示您希望 cdr 单元格为 FOO 来保存值 FOO 。实际上,这种 SETF 的出现可能会宏扩展为对 RPLACD

When you call SETF with the (rest foo) place and the foo value, you are saying that you want the cdr cell of FOO to hold the value FOO. In fact, this occurrence of SETF is likely to macroexpand into a call to RPLACD.

------------
| 42 | FOO |
------------
     ^
     |
    FOO



为什么REPL会永远循环?



REPL(打印)的 P部分尝试打印圆形结构。这是因为 SETF 的值是要评估的表单返回的值,而 SETF 的值是其第二个参数的值,即 FOO 。想象一下,您想用一个天真的算法编写一个cons单元格X:

Why does the REPL loop forever?

The "P" part of the "REPL" (print) tries to print your circular structure. This is because SETF's value is the one being returned from the form being evaluated, and the value returned by SETF is the value of its second argument, namely FOO. Imagine you want to write a cons cell X with a naive algorithm:

1. PRINT "("
2. PRINT the CAR of X
3. PRINT " . "
4. PRINT the CDR of X
5. PRINT ")"

但是,对于 foo ,步骤4将打印相同的结构,递归,并且永远不会终止。

However, for foo, step 4 will print the same structure, recursively, and will never terminate.

尝试设置 * PRINT-CIRCLE * 到T开头:

Try setting *PRINT-CIRCLE* to T first:

(setf *print-circle* t)

现在,您的REPL应该很高兴:

And now, your REPL should be happy:

CL-USER> (let ((foo (list 42)))
           (setf (rest foo) foo))
#1=(42 . #1#)

Sharpsign等于-符号 表示允许读者将表单的一部分影响到(读者)变量,例如#1 = ... ,然后再使用它,例如#1#。这样就可以在读取或打印过程中表示数据之间的圆形交叉引用。在这里,我们可以看到变量#1#表示cons单元格,其中 CAR 是42 CDR 本身是#1#

The "Sharpsign Equal-Sign" notation allows the reader to affect part of a form to a (reader) variable, like #1=..., and reuse it afterwards, e.g. #1#. This make it possible to represent circular cross-references between data, either during reading or printing. Here, we can see that the variable #1# denotes a cons-cell, where the CAR is 42 and the CDR is #1# itself.

这篇关于SETF既不终止也不报告错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆