clojure - 为什么 Clojure 习惯用法更喜欢返回 nil 而不是像Scheme 那样返回空列表?

标签 clojure idioms

来自a comment on another question ,有人说 Clojure 习惯用法更喜欢返回 nil 而不是像 Scheme 中那样返回空列表。这是为什么?

喜欢,

(when (seq lat) ...)

而不是

  (if (empty? lat)  
    '() ...)

最佳答案

我可以想到几个原因:

  • 逻辑区别。在 Clojure 中,nil 意味着什么都没有/没有值(value)。而 '() "空列表一个值 - 它恰好是一个空列表值。在概念和逻辑上区分这两者通常很有用。

  • 适合 JVM - JVM 对象模型支持空引用。并且相当多的 Java API 返回 null 表示“无”或“未找到值”。因此,为了确保轻松的 JVM 互操作性,Clojure 以类似的方式使用 nil 是有意义的。

  • 懒惰 - 这里的逻辑相当复杂,但我的理解是,使用 nil 表示“无列表”与 Clojure 的 lazy sequences 配合使用效果更好。由于 Clojure 默认是一种惰性函数式编程语言,因此这种用法成为标准是有意义的。请参阅 http://clojure.org/lazy 了解一些额外的说明。

  • “虚假” - 在编写检查集合的条件代码时,使用 nil 表示“无”也表示“假”,这很方便 - 因此您可以编写像 (if (some-map :some-key) ....) 这样的代码测试 HashMap 是否包含给定键的值。

  • 性能 - 测试 nil 比检查列表是否为空更有效......因此采用这种习惯用法作为标准可以带来更高性能的惯用代码

请注意,Clojure 中仍有一些函数确实返回空列表。一个例子是休息:

(rest [1])
=> ()

这个 question on rest vs. next 详细说明了为什么会这样......

关于clojure - 为什么 Clojure 习惯用法更喜欢返回 nil 而不是像Scheme 那样返回空列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6045404/

相关文章:

.net - 确定远程设备端点 UDP Clojure CLR

clojure - defn 与 let 关于分解的比较

c++ - 我们能否增加这种面向 key 的访问保护模式的可重用性?

Python 单行打印从 ASCII 数字转换的文本?

f# - 惯用的 F# - 简单统计函数

validation - 我应该使用函数还是宏来验证 Clojure 中的参数?

vector - Clojure:遍历一个向量的向量,找到第一个满足某个条件的向量

clojure - 延迟分区

scala - 我怎样才能使这个方法更具可扩展性

c++ - 分解复杂表达式的好的编码习惯用法是什么?