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

时间:2014-11-13 21:00:09

标签: scheme

据我所知,零是一个假值。那么为什么在下面的代码中它被视为True值,即为什么'被返回?

scm> (if 0 'a 'b)
'a

3 个答案:

答案 0 :(得分:5)

在Scheme中, false值为#f(尽管有时false别名也定义为相同的值),其他任何内容都被认为是真的 - 包括:{ {1}},0""等。在此表达式中清楚明了:

'()

(if 0 'a 'b) 是真实的,因此整个表达式的结果为0

答案 1 :(得分:0)

不同的语言会决定是否可以将非布尔值视为布尔值,以及哪些布尔值计为True vs False。有关某些语言中行为的比较,请参阅here

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

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

答案 2 :(得分:0)

大多数LISPers对空列表有同感。由于LISP的开始nil / ()也是唯一的错误值。 Scheme将#f引入为false并将()保留为多个报告的false,直到他们将()作为false值删除。因此,只有#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,您可以在库中执行此操作,并将其重命名为if(except (rnrs) if),然后您可以导入此而不是(rnrs)并获取此{{1}行为而不是标准。请注意,您不能更改使用rnrs或其他库所使用的if,因此您需要使yoru拥有所有特殊形式的版本,这些版本的行为与您想要的不同。阅读代码的人可能会感到困惑。