Lisp 组合DrRacket隐式else
为什么这样做有效Lisp 组合DrRacket隐式else,lisp,racket,Lisp,Racket,为什么这样做有效 (define (rev l) (cond ((null? l) l) (else (append (rev(cdr l)) (list (car l)))))) 输出: > (rev L1) (d c b a) > (rev L1) (a) 这不是吗 (define (rev l) (cond ((null? l) l) (append (rev(cdr l)) (list (car l))))) 输出: > (rev
(define (rev l)
(cond ((null? l) l)
(else (append (rev(cdr l)) (list (car l))))))
输出:
> (rev L1)
(d c b a)
> (rev L1)
(a)
这不是吗
(define (rev l)
(cond ((null? l) l)
(append (rev(cdr l)) (list (car l)))))
输出:
> (rev L1)
(d c b a)
> (rev L1)
(a)
在第二个示例中,过程append是谓词,因为它是一个过程,除f外的每个值都是true,所以它会执行后续的rev cdr l cond的术语必须放在括号中。没有显式的else,如果两个谓词都不匹配,则实现可以选择结果未定义的值 if是一个不同的条件,可能更适合这种情况
(define (rev l)
(if (null? l)
l
(append (rev (cdr l))
(list (car l)))))
更改缩进可以更容易地查看发生了什么:
(define (rev l)
(cond
[(null? l) l]
[else (append (rev(cdr l)) (list (car l)))]))
(define (rev l)
(cond
[(null? l) l]
[append (rev(cdr l))
(list (car l))]))
注意,在第二个版本中有一个子句
[append (rev(cdr l))
(list (car l))]))
当计算cond表达式时,它会尝试计算每个左侧,直到找到一个给出非false值的表达式。这里,左侧的append计算为append函数,它是一个非false值
接下来发生的事情是对右侧进行评估。由于右侧有一个隐式开始,因此将对其进行计算:
(begin
(rev(cdr l))
(list (car l)))
总结:您意外地编写了一个语法正确的表达式,但其含义与您预期的不同
请注意,如果在cond中的子句周围使用方括号,则更容易发现错误。方括号[]和标准的含义相同