SCd*_*CdF 10 protocols clojure multimethod
所以我想java.awt.Color用于某些东西,我希望能够编写这样的代码:
(use 'java.awt.Color)
(= Color/BLUE (- Color/WHITE Color/RED Color/GREEN))
Run Code Online (Sandbox Code Playgroud)
看一下它的核心实现-,它具体谈到clojure.lang.Numbers,对我来说这意味着我没有做任何事情来"挂钩"到核心实现并扩展它.
在互联网上四处看看,人们似乎有两件不同的事情:
编写自己的defn -函数,只知道他们感兴趣的数据类型.使用你可能最终为命名空间添加前缀,所以类似于:
(= Color/BLUE (scdf.color/- Color/WHITE Color/RED Color/GREEN))
或者use在命名空间中使用clojure.core/-,并在需要数字数学时使用.
在您的-实现中编写一个特殊情况,该实例将clojure.core/-在您的实现传递时通过Number.
不幸的是,我不喜欢其中任何一个.第一个可能是最干净的,因为第二个假设你关心做数学的唯一事情是他们的新数据类型和数字.
我是Clojure的新手,但我们不应该在这里使用Protocols或Multimethods,这样当人们创建/使用自定义类型时,他们可以"扩展"这些功能,使它们无缝地工作?有没有理由+,-等等不支持这个?(或者他们呢?他们似乎没有阅读我的代码,但也许我读错了).
如果我想将自己的扩展编写到常见的现有函数(例如+其他数据类型),我该怎么做才能使它与现有函数和其他可能的数据类型很好地配合?
它并非完全是为此而设计的,但core.matrix可能会对您感兴趣,原因如下:
(+ [1 2] [3 4]) => [4 6]).值得研究如何完成:基本上运算符是调用协议的常规函数,每种数据类型都通过以下方式提供协议的实现:extend-protocoljava.awt.Color工作作为core.matrix实现(即作为4D RGBA向量).我在这里用BufferedImage做了类似的事情:https://github.com/clojure-numerics/image-matrix.如果您实现了基本的core.matrix协议,那么您将获得整个core.matrix API来处理Color对象.这将为您节省大量实施不同操作的工作.不在基于协议的核心中进行算术运算(并使它们仅进行数字运算)的可能原因是性能。协议实现需要额外的查找来选择所需功能的正确实现。尽管从设计的角度来看,拥有基于协议的实现并在需要时扩展它们可能感觉很好,但是当您有一个紧密的循环多次执行这些操作时(这是算术运算的非常常见的用例),您会开始感觉由于运行时发生的每个操作的额外查找而导致性能问题。
如果您在自己的命名空间中为自己的数据类型(例如:)单独实现color/-,那么由于直接调用该函数,它的性能会更高,并且它还使事情对于特定情况更加明确和可定制。
这些函数的另一个问题是它们的可变特性(即它们可以接受任意数量的参数)。这是提供协议实现的一个严重问题,因为协议扩展类型检查仅适用于第一个参数。
| 归档时间: |
|
| 查看次数: |
507 次 |
| 最近记录: |