括号中的任何 Scheme 形式都是一个应用程序,例如(sin 42)
或(42 sin)
。第一个sin
作为带参数的函数调用42
并产生一个值;第二个尝试42
使用参数调用sin
,但42
不是过程,因此会导致错误。同样(42)
是没有参数的应用程序;它仍然必须有一个过程作为它的第一部分应用,在没有参数的情况下被调用,对吧?在 Scheme 中,括号很重要,它们不仅仅用于对内容进行分组(因为它们可能在其他一些语言中)。所以额外的括号会导致额外的尝试评估结果,这是一个布尔值,即不是一个过程,所以这是一个错误。
那么,'#f
就是#f
;类似地#t
(他们都对自己进行评估);并且条件1与 just 相同(产生相同的布尔结果集)((我们不能使用1来比较布尔值,它应该只与数字一起使用)):(= test #t)
(equal? test #t)
test
=
(define (odd? x)
(cond
((= x 0) #f)
((= x 1) #t)
((even? (- x 1)) #f)
(else #t)))
此外,(if test #f else...)
与以下内容相同(if (not test) else... #f)
:
(define (odd? x)
(cond
((= x 0) #f)
((= x 1) #t)
((not (even? (- x 1))) #t)
(else #f))) ; (else ...) is like (#t ...)
使用逻辑连接词可以合并具有相同结果的子句,并且可以重新排列互斥子句(可以通过显式保护实现互斥性):
(define (odd? x)
(cond
((and (/= x 0) ; a guard
(or (= x 1)
(not (even? (- x 1))))) #t)
((or (= x 0) #t) #f)))
但(cond (test #t) (else #f)
就是(if test #t #f)
这样test
:
(define (odd? x) (and (> x 0) ; `>` is better
(or (= x 1)
(not (even? (- x 1))))))
守卫(> x 0)
可以防止负x
es 的失败。
但是,这是完全错误的。为n
奇,n-1
必为偶,而不是相反!
(define (odd? x) (and (> x 0) ; work only for positive integers
(or (= x 1)
(even? (- x 1)))))
我们可以写(not (odd? (- x 1)))
,但它不会是尾递归的。这将是尾递归模 cons(not
用作“构造函数”),但由于某种历史性的侥幸原因2,TRMC 优化不是 Scheme 实现所必需的。and
和forms 中的最后一个表达式or
实际上是在 tail position。但不在not
. ((2尽管早在1974年就被描述了。))
对 的定义重复相同的操作even?
。