我正在尝试在Scheme中使用,但是我不知道为什么列表的最后一个元素出现。#void>。
这是我的代码
(define (genlist x y)
(when
(< x y)
(cons x (genlist (+ x 1) y))))
这是我的输出=>
(2 3 4 5 6 7 8 9 . #void>)
答案 0 :(得分:2)
您需要使用(if (< x y) (cons ...) '())
来生成适当的列表。
when
(与之相对应的unless
)主要用于在不使用结果的情况下产生副作用(例如打印出一些东西)。
例如(when debug-mode? (print "got here"))
答案 1 :(得分:2)
when
是一个带有隐含begin
的ifs。以下示例相同:
(if (any odd? lst)
(begin
(set! some-binding #t)
(display "Found an odd element")))
(when (any odd? lst)
(set! some-binding #t)
(display "Found an odd element"))
您可以在谓词中使用unless
而不是not
:
(if (not (any odd? lst))
(set! some-binding #f))
(unless (any odd? lst)
(set! some-binding #f))
彼得·诺维格(Peter Norvig)写了一本关于Lisp style的好书,他在书中谈到了这一点:
请确保您的数据抽象所要求的具体程度,但仅此而已。
因此,尽管您可以使用if
编写所有逻辑,但这并不是最容易阅读的代码。其他人可能会使用术语principle of least surprise。即使这本书是针对Common Lisp的,也可以在Scheme中使用其中的大部分内容。如果您想对任何Lisp方言进行编程,这是一本好书。
对于when
和unless
而言,这对Scheme更好,因为您不知道在谓词为#f
的情况下,如果在CL中谓词求值,则可能返回什么实现。 when
,因为在这种情况下注定要返回nil
。
在您的代码中,您试图返回某些内容,让实现选择在谓词失败时应该发生的情况,这是导致#<void>
的原因。当退货时,您应该始终使用两副武装的if
:
(if test-expression
then-expression
else-expression)
请注意,没有else
关键字。
答案 2 :(得分:1)
当我们需要编写不包含when
部分的if
时,和/或需要在else
中编写多个表达式时,我们使用if
。仅返回最后一个表达式的值,因此我们主要将其用于副作用。为了更好地理解它,在球拍中这样:
(when <condition>
<exp1>
<exp2>
<exp3>)
等效于此:
(if <condition>
(begin
<exp1>
<exp2>
<exp3>)
(void)) ; implementation-dependent
除了条件用unless
包围之外,(not ...)
的注意事项也相同。
问题的根源(以及没有if
的{{1}}是代码味道的原因)是您的代码无法处理else
时的情况。问问自己,在这种情况下您应该怎么做?简单,返回一个空列表!这是代码中缺少递归的基本情况。