【问题标题】:Is there a way in Clojure to make a protocol (or other type structure) closed to extension?Clojure 中有没有办法使协议(或其他类型的结构)对扩展关闭?
【发布时间】:2015-01-10 03:59:41
【问题描述】:

在 Clojure 中,我们有各种扩展机制:extend-typeextend-protocolextend

现在我们做一些假设:

这个问题有一些背景。 Philip Wadler 谈到了the expression problemThis discussion is expanded here 因为它涉及到代数数据类型

对于代数数据类型,

在事物上添加新操作非常便宜:您只需定义一个新函数。这些东西上的所有旧功能继续保持不变。

添加一种新的东西非常昂贵:您必须为现有数据类型添加一个新的构造函数,并且您必须编辑和重新编译每个使用该类型的函数。

类,

添加一种新的东西非常便宜:只需添加一个新的子类,并根据需要在该类中为所有现有操作定义专门的方法。超类和所有其他子类继续保持不变。

在事物上添加新操作非常昂贵:您必须向超类添加新方法声明,并可能向每个现有子类添加方法定义。在实践中,负担因方法而异。

现在,这背后的驱动力(他们是从 Haskell 的角度说的)是函数式编程中的一个概念,称为 total functions。 (这与parametricity in functional programming 有关)。 所有函数benefit 是编写的程序可证明终止

现在,这似乎是计算机科学的一项毛茸茸的好处 - 但它对 Clojure 世界中的我们来说是一个真正的好处。像Steve MinerReid Draper 这样的人正在研究simple-check。现在,如果我们有一个总函数,那么我们可以确信给定一个输入域,我们可以保证输出的范围。

现在,如果您可以关闭扩展类型,您可以更轻松地将函数声明为“总函数” - 并使简单检查等工具的工作更轻松、更全面。 (并且有更大的信心让函数按照它所说的去做)。

现在看起来 Ambrose' 正在努力实现 core.typed is starting to approach 这个目标。

所以我的问题是:在 Clojure 中有没有办法使协议(或其他类型的结构)对扩展关闭? (或者这只是完全不习惯?)

【问题讨论】:

  • 你的意思是“有没有办法在 Clojure 中使 record(或其他类型的结构)对扩展关闭?

标签: haskell clojure extends


【解决方案1】:

reify 创建对象会给你一个匿名类型的对象。由于该类型是匿名的,因此无法将其扩展到任何进一步的协议。但这只是一方面;它不会阻止其他人将 reify 主体中的协议扩展到 other 类型/记录。

我认为没有任何方法可以通过记录、类型或协议来实现这一点(除非可能通过深入研究底层实现)。

【讨论】:

    猜你喜欢
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多