为什么是';0';在Scheme中的if语句中被视为真值?

为什么是';0';在Scheme中的if语句中被视为真值?,scheme,Scheme,我的理解是零是一个错误的值。那么为什么在下面的代码中将其视为真值,即为什么返回“a” scm> (if 0 'a 'b) 'a 在Scheme中,唯一的假值是#f(尽管有时假别名也定义为相同的值),其他任何值都被认为是真的,包括:0,“,”(),等等。在这个表达式中非常清楚: (if 0 'a 'b) 值0是真实的,因此整个表达式的计算结果为'a。不同的语言对是否可以将非布尔值视为布尔值以及哪些值算作真与假做出不同的决定。有关某些语言中行为的比较,请参见 Scheme是一种做出决策的语

我的理解是零是一个错误的值。那么为什么在下面的代码中将其视为真值,即为什么返回“a”

scm> (if 0 'a 'b)
'a
在Scheme中,唯一的假值是
#f
(尽管有时
别名也定义为相同的值),其他任何值都被认为是真的,包括:
0
”()
,等等。在这个表达式中非常清楚:

(if 0 'a 'b)

0
是真实的,因此整个表达式的计算结果为
'a

不同的语言对是否可以将非布尔值视为布尔值以及哪些值算作
做出不同的决定。有关某些语言中行为的比较,请参见

Scheme是一种做出决策的语言:

  • 您可以在需要布尔值的上下文中使用非布尔值
  • 除规范假符号
    #f
    以外的任何值都是真实的

大多数口齿不清的人对空列表也有同样的感觉。自LISP
nil开始以来,nil
/
()
也是唯一的假值。方案将
#f
引入为假,并将多个报告的
()
保留为假,直到它们将
()
作为假值删除。因此,只有
#f
被认为是错误的

您无法轻松更改报告,因此我建议您制定一个程序来执行您想要的操作:

(define (boolean x)
  (not (or (eq? x '())
           (eq? x #f)
           (eqv? x "")
           (eqv? x 0))))

(boolean "")           ; ==> #f
(if (boolean 0) 'a 'b) ; ==> b
或者,如果您经常使用此选项,您可以将自己设置为宏:

(define-syntax mif
  (syntax-rules ()
    ((_ predicate consequent alternative)
     (if (boolean predicate) consequent alternative))))

(mif 0 'a 'b) ; ==> b

使用R6RS和R7RS,您可以在库中执行此操作,并将其与
(除了(rnrs)if)
一起重命名为
if
,然后您可以导入它而不是
(rnrs)
,并获得此
if
行为而不是标准。请注意,如果与RNR或其他库一起使用,则无法更改
,因此您需要为所有特殊表单制作自己的版本,这些表单的行为与您想要的不同。阅读您的代码的人可能会感到困惑

“我的理解是零是一个错误的值。”根据谁的说法?