我正在学习Scheme。我最近花了(太多!)时间试图找到程序中的错误,然后才意识到我错过了cond子句中的'else'字样。但在这种情况下的行为似乎有点奇怪。只用一个简单的程序(下面)试验条件,'else'在else子句中按预期显示,但也会显示,但没有'else',会显示周围的双引号和未解释的新引号字面打印。任何人都可以向我解释发生了什么事吗? TIA。
(define (foo x)
(cond ((eq? x 0) (display "zero\n"))
(display "whatever\n")))
(define (bar x)
(cond ((eq? x 0 ) (display "zero\n"))
(else (display "whatever\n"))))
In the repl window:
Welcome to DrScheme, version 4.1.5 [3m].
Language: Pretty Big; memory limit: 128 megabytes.
> (foo 0)
zero
> (bar 0)
zero
> (foo 2)
"whatever\n"
> (bar 2)
whatever
>
答案 0 :(得分:17)
“else”只是“true”的同义词。读取cond的方法是作为一系列测试,其中第一个测试是真的导致要评估表单。
(cond ( (test) (do this) )
( (test) (do this) ) )
这是你的第一个
(cond ((eq? x 0) (display "zero\n"))
(display "whatever\n")))
cond查看(eq? x 0)
并确定其为假。下一个子句是(display "whatever\n")
。它会查看display
,因为display
不是nil
,所以它是真的。然后它会计算字符串"whatever\n"
,它只是评估自己。那么cond的值就是"whatever\n"
。
现在,这是你的第二个:
(cond ((eq? x 0 ) (display "zero\n"))
(else (display "whatever\n"))))
这里,第一个测试是假的,然后继续进行第二个测试,即else
并且评估为真。 (如果你考虑一下,那就是“else”在正常的if-then-else中意味着什么:“对于以前没有一个测试都是真的所有情况都是如此。”)
现在,它后面的表格是(display "whatever\n")
。这是一个将字符串参数发送到控制台并且不返回任何内容的函数,因为这就是显示器正在执行的操作。在另一个方案中,它可能返回其字符串值以及打印它,在这种情况下,您将看到
whatever
"whatever\n"
答案 1 :(得分:9)
在foo
函数中,cond
语句将display
评估为要测试的条件。由于确实存在名为display
的符号,因此它的计算结果为true,因此"whatever\n"
将作为(foo 2)
的结果进行评估。