为什么Clojure之父认为Scheme的true/false是有问题的?

39
在这个视频中,Rich Hickey向Lisp程序员介绍了Clojure。
在01:10:42时,他谈到了Clojure/Common Lisp/Scheme/Java中的nil/false/end-of-sequence/'()。他说:“Scheme有true和false,但它们是有问题的。”

slide

我不明白他为什么这样说,为什么他认为它是“破损的”?

1
这张表看起来有点混乱。我宁愿不尝试去“解释”它。 - Rainer Joswig
3个回答

47

我觉得你更愿意从第一手资料中了解,所以这里是Rich发布的信息的一个精选摘录:

Scheme #t几乎是没有意义的, 因为Scheme条件测试为#f/non-#f,而不是#f/#t。 我认为#f的价值几乎没有什么用处, 并且基于它来编写条件语句意味着需要编写大量的(if (not (null? x))...,而在Clojure/CL中,(if x...就足够了, 这会在处理序列、过滤器等时显著降低表达能力。

那条信息中的链接也很有价值,尽管第二个链接可能有点诗意。


2
老实说,我脑海中仍然有疑问。所以我只能给你一半的分数。不好意思。 - yehnan
2
如果我理解正确的话,Rich 的抱怨是在 Scheme 中,nil 在条件语句中会被评估为 true(而不是 false)?这对我来说似乎是一个糟糕的设计。 - Nathan Davis
2
@Nathan - 的确,它的结果是 #t。在技术上讲,'() 评估为 #t,因为 Scheme 缺乏 nil,除非你定义它。 - Arthur Shipkowski

9

从您发布的图表中,我认为Scheme与图表中的所有其他语言不同,使用除nilfalse之外的某些东西来表示end-of-seq。由于'()non-#f,因此它在条件语句中会作为truthy值,但在检查序列末尾时则被视为falsy值。


好的,我同意你的观点。但是你的观点还没有满足我的需求。为什么要称它为“损坏”的呢? - yehnan
6
如果同一件事情在不同的上下文中可能是真或假,我猜有些人会认为它是有问题的。 - Michael Kohl
在我看来,列表末尾和false是两个不同的概念,Scheme通过区分它们来正确处理。他应该在那张图表中包括JavaScript,与其7个false值相比,Clojure看起来更明智。 - Jörn Horstmann
1
clojure => (if '() 1 2) 返回1,因此 '() 作为 #t 值不可能是调用它失败的原因。(除非 Rich 认为 Clojure 的布尔值也是有问题的) - subsub
@subsub:这正是我上一句话的意思。有些人可能认为Scheme使用通常为真值的值来表示序列结束是不合理的。然而,在Clojure中并不如此,因为()(在Clojure中不需要引号)是真值,因此也不用于表示序列的结尾。有些人,比如Jörn,对此持不同意见,我也能理解他们的观点。 - Michael Kohl
@Michael-kohl:啊,我以为你在最后一句话中提到的是Scheme。 - subsub

3
在Scheme中,任何值(除了#f,即False)都可以在条件测试中用作True。更多信息请参见此处更新 忘记这个答案,因为Clojure当然也是一样的。我不喜欢所有非false值的隐式真实性,例如在(println(if 1“true”“false”))中。就我个人而言,我认为这是有问题的,但Rich可能想到了其他事情。

1
那么?你能提供更多的解释吗? - yehnan
3
这与Clojure的(nil/false)和Common Lisp的(nil)相同。这不可能是原因,这是正确的做法(在我看来)。 - nickik
关于您的更新:为什么Rich应该考虑这个bronken,他为什么要以同样的方式实现它? - nickik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接