我可以在Scheme中创建一个循环数据结构,如下所示:
(define my-pair (cons 1 1))
(set-car! my-pair my-pair)
是否可以在Scheme中创建循环数据结构而不使用变异? (我正在准备关于引用计数限制的讲座。)
答案 0 :(得分:5)
您可以使用闭包创建一个惰性列表:
; The infinite list (1 1 1 ...
(define ones
(letrec ((x (cons 1 (lambda () x))))
x))
> ones
'(1 . #<procedure>)
> ((cdr ones))
'(1 . #<procedure>)
验证循环的身份检查:
> (eq? ones ((cdr ones)))
#t
答案 1 :(得分:3)
通过关注相关问题(Why don't purely functional languages use reference counting?)的链接,我看到了对letrec
的引用。这让我意识到我确实可以创建一个循环的数据结构&#34;在Scheme中:
(letrec ((add (lambda (x y) (if (>= x y) (+ x y) (add2 y x))))
(add2 (lambda (x y) (if (>= x y) (+ x y) (add y x)))))
(add 1 5))
答案 2 :(得分:1)
添加到@molbdnilo 回答大多数方案 imeplemetation 定义 delay
和 force
,
允许创建所谓的流(定义在
SICP).
; The infinite list (1 1 1 ...
(define ones (cons 1 (delay ones)))
> ones
(1 . #<promise>)
> (force (cdr ones))
(1 . #<promise>)
(eq? ones (force (cdr ones)))
#t
delay
和 force
可以实现为只是 lambda 表达式的宏。您甚至可以编写处理流的过滤器或映射等过程。
编辑:
同样由 R7RS 定义,您可以创建带有基准标签的真实圆形列表。
(define x '#0=(a b c . #0#))
x
;; ==> #0=(a b c . #0#)
(eq? x (cdddr x))
#t
如果 Scheme 完全支持 R7RS 规范,它应该允许以相同的方式定义和显示循环列表。请注意,在 Kawa Scheme 中,它将循环打印以显示您需要使用 (write x)
的循环列表。