Ask*_*ker 8 polymorphism clojure conditional-statements
为什么 Clojure 中的 multimethods 不能简单地替换为 cond 表达式?
在查看了 Ch 中多方法的简单示例后,我受到启发提出了问题。Russ Olsen 的《Getting Clojure》一书中的 5 篇。
在对类似问题(Clojure 中多方法与 cond 的性能)的回复中,用户 Daniel Compton 说
多方法允许开放扩展;其他人可以扩展您对任意表达式的多方法调度。Cond 表达式对其他人甚至您自己的代码的扩展是封闭的。
但是我完全不清楚在这种情况下“开放扩展”和“封闭扩展”是什么意思,因为在我看来,multimethods 和 cond 表达式都可以很容易地编辑或扩展。
那么......为什么不应该简单地用 cond 表达式替换 Clojure 中的多方法?
或者,等效地,如何或何时使用多方法比使用 cond 更好或更优雅?
这里的关键点是“允许开放扩展”。任何人都可以为您的多方法添加新的分支——acond是硬编码的:新的调度必须添加到cond适当的代码中。
假设:您有一些小部件并且想要绘制它们。小部件有一个:type,您想draw在该类型上调度如何。
cond为您所知道的所有小部件编写一个大文件会起作用。但是现在对于每个新小部件,您都必须触摸cond源代码并对其进行修改。这可以是完全的罚款,例如实际应用中,并不需要扩展。
对多方法做同样的事情,任何人都可draw以为他们的小部件实现一个。因此,您在编写代码时并不了解所有这些。这使它成为例如图书馆更好(甚至强制)的方法。
现在想象一下,你已经决定cond了你正在编写的库中的方法。任何一个新的widget现在必须自己写
draw,派出的第一个绘制,然后打电话给你的draw。此外,他们还必须确保,他们draw在任何地方都draw被调用,在那里你
被调用让它工作(这通常是不可能的)。
直接在 Clojure 核心中使用多方法的一个流行示例是
print-method. 通过这种方式,任何人都可以为他们的类型实现“序列化”并很好地发挥作用。
其他值得一看的例子是 clojure.test 和integrant。