从对另一个问题的评论中,有人说Clojure成语更喜欢返回nil而不是像Scheme中的空列表.这是为什么?
喜欢,
(when (seq lat) ...)
Run Code Online (Sandbox Code Playgroud)
代替
(if (empty? lat)
'() ...)
Run Code Online (Sandbox Code Playgroud)
mik*_*era 23
我可以想到几个原因:
逻辑区别.在Clojure中,没有任何意义/缺乏价值.而'()'空列表是一个值 - 它恰好是一个空列表的值.它在概念和逻辑上通常很有用,可以区分这两个.
适合JVM - JVM对象模型支持空引用.而且很多Java API都返回null表示"没有"或"找不到值".因此,为了确保简单的JVM互操作性,Clojure以类似的方式使用nil是有意义的.
懒惰 - 这里的逻辑很复杂,但我的理解是使用nil作为"无列表"可以更好地使用Clojure的懒惰序列.由于Clojure默认是一种惰性函数式编程语言,因此这种用法是标准的.有关其他说明,请参见http://clojure.org/lazy.
"Falsiness" - 在编写检查集合的条件代码时,使用nil表示"无"并且表示"假"也很方便 - 因此您可以编写代码(if (some-map :some-key) ....)来测试hashmap是否包含给定键的值.
性能 - 测试nil比检查列表以查看它是否为空更有效...因此采用这个成语作为标准可以导致更高性能的惯用代码
请注意,Clojure中仍然存在一些返回空列表的函数.一个例子是休息:
(rest [1])
=> ()
Run Code Online (Sandbox Code Playgroud)
关于休息与下一个问题的这个问题详细解释了为什么这是......
还要注意,集合类型和nil的并集形成一个monoid,连接monoid加上nil和monoid零.因此,nil将空列表语义保持在连接状态,同时还表示错误或"缺失"值.
Python是另一种常见的monoid身份表示错误值的语言:0,空列表,空元组.
由于空集合的行为类似于
true布尔上下文,因此您需要一个习惯用法来测试集合中是否有任何要处理的东西。幸运的是,Clojure提供了这样一种技术:Run Code Online (Sandbox Code Playgroud)(seq [1 2 3]) ;=> (1 2 3) (seq []) ;=> nil
在其他Lisps中,例如Common Lisp,空列表用来表示nil。这称为nil punning,仅在空列表为falsey时才可行。返回nil这里是Clojure重新引入零校正的方式。
| 归档时间: |
|
| 查看次数: |
6028 次 |
| 最近记录: |