在Clojure中,我们有各种扩展机制:extend-type
,extend-protocol
,extend
。
现在我们做出一些假设:
这个问题有一些背景知识。 Philip Wadler谈到the expression problem。 This discussion is expanded here与代数数据类型相关:
使用代数数据类型
在事物上添加新操作非常便宜:您只需定义一个新功能。这些事情的所有旧功能继续不变。
添加新类型的东西非常昂贵:您必须添加一个新的构造函数和现有的数据类型,并且您必须编辑并重新编译使用该类型的每个函数。
使用课程
添加一种新东西非常便宜:只需添加一个新的子类,并根据需要在该类中为所有现有操作定义专用方法。超类和所有其他子类继续保持不变。
在事物上添加新操作非常昂贵:您必须向超类添加新方法声明,并可能向每个现有子类添加方法定义。在实践中,负担因方法而异。
现在这背后的驱动程序(他们从Haskell的角度讲)是一个名为total functions的函数式编程概念。 (这与parametricity in functional programming)有关。 {em>总函数的benefit是所编写的程序可证明终止。
现在看起来似乎是一种蓬松的计算机科学的好处 - 但它在Clojure世界中对我们有实实在在的好处。像Steve Miner和Reid Draper这样的人正在研究simple-check。现在,如果我们有一个总函数,那么我们可以放心,给定一个输入域,我们可以保证输出范围。
现在,如果你可以关闭一个类型到扩展名,你可以更容易地声明一个函数一个'总函数' - 使简单检查等工具的工作更轻松,更全面。 (并且更有信心功能可以完成它所说的功能)。
现在看起来像Ambrose'处理core.typed is starting to approach此目标。
所以我的问题是:在Clojure中是否有办法让协议(或其他类型结构)接近扩展? (或者这只是完全非惯用的?)
答案 0 :(得分:1)
使用reify
创建对象会为您提供一个匿名类型的对象。由于该类型是匿名的,因此无法将其扩展到任何其他协议。但这只是单方面的;它并没有阻止其他人将reify主体中找到的协议扩展到其他类型/记录。
我不认为有任何方法可以通过记录,类型或协议来实现这一目标(除非可能通过挖掘底层实现)。