当cond没有其他分支并且条件不满意时,编译器不会抱怨

时间:2015-08-25 12:37:44

标签: racket

我有以下球拍代码:

#lang racket

(define (for-each proc items) 
  (cond ((not (null? items)) 
    (proc (car items)) 
    (for-each proc (cdr items))))) 

(for-each (lambda (x) (newline) (display x))
    (list 57 321 88))

因为在打印88之后条件不满意,并且Racket的文档说:

  

如果question-expressions中没有一个计算为true,则cond的值是else子句的answer-expression。如果没有别的,cond报告错误。

所以预期的结果是错误,但是我得到了正确的输出:

57
321
88

有人可以告诉我为什么吗? (ps:我使用DrRacket 6.2)

2 个答案:

答案 0 :(得分:3)

稍微更改缩进:

(define (for-each proc items) 
  (cond
    [(not (null? items)) (proc (car items)) 
                         (for-each proc (cdr items))]))

致电(for-each f (list 1 2 3)) 将调用该函数并将proc绑定到fitems绑定到'(1 2 3)

测试(not (null? items))为真,因为'(1 2 3)非空。 因此评估右侧。右手做两件事: 1.)(proc (car items))使用列表中的第一个元素(此处为1)然后2)调用f。致电(for-each proc (cdr items))。这里(cdr items)成为'(2 3)。

最终将使用for-each调用(for-each f '())。 此时(not (null? items))将评估为#fcond将尝试下一个子句。由于没有其他条款cond将返回void

文档说:

If no cond-clauses are present, the result is #<void>.

注意:教学语言中的cond将返回错误。教学语言中的结构通常报告错误,有可能射击自己的脚。

答案 1 :(得分:1)

我不知道你从哪里获得这些信息。引用spec

  

cond中的最后一个test-expr可以用else替换。在评估方面,else作为#t的同义词,但它澄清了最后一个条款是为了捕获所有剩余的案例。如果没有使用else,则有可能没有test-exprs产生真值;在这种情况下,cond表达式的结果是#void。