【问题标题】:Circular lists in guileguile 中的循环列表
【发布时间】:2019-09-12 16:38:06
【问题描述】:

我正在用 guile 测试这段代码:

> (define xxx  (let ((x '(1 2 3))) (set-cdr! (cddr x) x) x))
> xxx

它显示 (1 2 3)

但是这个:

(define x '(1 2 3))
(set-cdr! (cddr x) x)
x
=> (1 2 3 . #-2#)

创建循环列表

为什么第一个代码在 guile 中不起作用?如果您不了解 guile 我只是想知道它是否应该按照方案规范工作,不知道在哪里可以搜索这些东西。

【问题讨论】:

  • "它显示 (1 2 3)" - 不,它没有。它会引发错误:In procedure set-cdr!: Wrong type argument in position 1 (expecting mutable pair): (3)。你用的是什么诡计版本?
  • 它们产生相同的循环结果,导致 Guile 2.0.13 here。不过,我相信 2.0 与任何 Scheme 标准都相去甚远。
  • 这两种方案都不是有效的方案,因为您正在尝试修改常量引用的文字数据。因此,如果实现打印了"BaNaNa",它仍然可以。

标签: scheme lisp circular-reference guile


【解决方案1】:

您的示例的问题是 - 它们不起作用。他们都没有。我不知道第一个是如何返回(1 2 3) 的。但是,当您在两个示例中解决相同的问题时,它们会按预期工作并创建循环列表。

有问题?

'(1 2 3)(quote 1 2 3)(list 1 2 3) 非常不同。它们都“看起来”相同,但第一个是静态列表,您无法修改它。只有使用list 函数(以及cons)创建的列表是您可以修改的列表。

修复

(define xxx
  (let ((x (list 1 2 3)))
    (set-cdr! (cddr x) x)
    x))

xxx ;; => (1 2 3 . #-2#)

第二个例子也是如此:

(define x (list 1 2 3))
(set-cdr! (cddr x) x)

请在发布前测试您的代码。

【讨论】:

  • 第二个代码在 guile 中运行,这正是我正在测试的代码,可能 (quote 1 2 3)define 一起使用时工作方式不同。不知道'(1 2 3)(list 1 2 3) 不同。但是如果quote 的工作方式与list 不同,那么为什么(let ((x '(1 2 3))) (append! x '(10))) 可以这样工作?
  • 我也在 guile (v 2.2.4) 上测试它。我遇到了一个错误。不知道为什么你的诡计不同。
  • 后来 guile 得到了内存保护和错误。旧版本没有这种保护。
猜你喜欢
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 2021-11-25
  • 2021-02-24
  • 2021-12-20
  • 2020-05-29
相关资源
最近更新 更多