【发布时间】:2019-02-08 02:33:48
【问题描述】:
背景: 几周前我在 guile 1.8.8 方案中做一个项目,有点生疏,我忘记了内置的 @ 987654321@ 函数,所以我自己滚动。不久之后,我遇到了一个看似无望的错误,在该错误中调用没有副作用的函数会改变程序其余部分的流程(正常工作并通过一些单元测试与完全崩溃)早就回来了。以前返回 (A B C D) 之类的几段代码现在只返回 (A),导致许多问题。
最小工作示例:经过几天的精简,我将问题集中到了这段独立的代码中:
(define (my-reduce fun ls)
(if (null? (cdr ls))
(car ls)
(my-reduce fun (cons (fun (car ls) (cadr ls))
(cddr ls)))))
(format #t "~a " (my-reduce + '(1 2 3)))
(format #t "~a " (my-reduce or '(1 2 3)))
(format #t "~a~%" (my-reduce + '(1 2 3)))
打印出6 1 1,而不是预期的6 1 6。
补充意见:
- 将第二行设置为
+会产生预期的6 6 6。 - 将第二行设置为
and会产生6 3 3。 -
+之后的附加行会产生附加的1s 或3s,具体取决于第二行的设置。所以,序列+or++导致输出6 1 1 1。 -
and或or在第一行之后的附加行不会切换回输出。因此,如果序列为+andor+,则输出为6 3 3 3。似乎,一旦我将or或and传递给(my-reduce),函数就会以它作为参数永久“卡住”。 - 我还注意到,将
and或or传递给内置的(reduce)函数会导致类型错误,因为它们在技术上是宏而不是函数。 - 按照同样的思路,我注意到将
or换成(lambda (x y) (or x y))会产生预期的输出。因此,这里的关键似乎是将宏传递给我自制的 reduce 函数会导致问题。
问题:这是怎么回事?为什么用and 或or 调用(my-reduce) 会导致这种意外行为?这与那些“函数”实际上是宏这一事实有关吗?
提前感谢您的帮助。这个真的把我难住了!
【问题讨论】: