【发布时间】:2015-01-10 03:59:41
【问题描述】:
在 Clojure 中,我们有各种扩展机制:extend-type、extend-protocol、extend。
现在我们做一些假设:
- Clojure is a dynamic语言
- Clojure 的社区更喜欢a particular idiomatic style
这个问题有一些背景。 Philip Wadler 谈到了the expression problem。 This discussion is expanded here 因为它涉及到代数数据类型:
对于代数数据类型,
在事物上添加新操作非常便宜:您只需定义一个新函数。这些东西上的所有旧功能继续保持不变。
添加一种新的东西非常昂贵:您必须为现有数据类型添加一个新的构造函数,并且您必须编辑和重新编译每个使用该类型的函数。
类,
添加一种新的东西非常便宜:只需添加一个新的子类,并根据需要在该类中为所有现有操作定义专门的方法。超类和所有其他子类继续保持不变。
在事物上添加新操作非常昂贵:您必须向超类添加新方法声明,并可能向每个现有子类添加方法定义。在实践中,负担因方法而异。
现在,这背后的驱动力(他们是从 Haskell 的角度说的)是函数式编程中的一个概念,称为 total functions。 (这与parametricity in functional programming 有关)。 所有函数的benefit 是编写的程序可证明终止。
现在,这似乎是计算机科学的一项毛茸茸的好处 - 但它对 Clojure 世界中的我们来说是一个真正的好处。像Steve Miner 和Reid Draper 这样的人正在研究simple-check。现在,如果我们有一个总函数,那么我们可以确信给定一个输入域,我们可以保证输出的范围。
现在,如果您可以关闭扩展类型,您可以更轻松地将函数声明为“总函数” - 并使简单检查等工具的工作更轻松、更全面。 (并且有更大的信心让函数按照它所说的去做)。
现在看起来 Ambrose' 正在努力实现 core.typed is starting to approach 这个目标。
所以我的问题是:在 Clojure 中有没有办法使协议(或其他类型的结构)对扩展关闭? (或者这只是完全不习惯?)
【问题讨论】:
-
你的意思是“有没有办法在 Clojure 中使 record(或其他类型的结构)对扩展关闭?”