Clojure协议与类型

时间:2012-05-22 23:40:40

标签: clojure

声明

尽管有标题,但这是一个真实的问题,而不是对Emacs / Vi火焰战的尝试。

上下文

我已经使用Haskell几个月了,写了一个小~10K的LOC解释器。在过去的一年里,我转到了Clojure。很长一段时间,我一直在努力克服Clojure缺乏的类型。然后我转而使用Clojure中的defrecords,现在,切换到Clojure的defprotocols。

我真的很喜欢defprotocols。实际上,不仅仅是类型。

我现在处于我的Clojure功能的位置,因为它的文档字符串,我只是指定:

* the protocols of the inputs
* the protocols of the outputs

使用它,看起来我现在有一个ad-hoc类型系统(不是编译器检查;但人工检查)。

问题

我怀疑我缺少哪些类型的东西。类型通过协议提供什么?

3 个答案:

答案 0 :(得分:2)

质疑问题......

您的问题"什么[do]类型提供协议?"对我来说似乎很尴尬。类型和协议是垂直的;他们描述不同的东西。 类型/记录定义了数据的结构,而协议定义了一些行为或功能的结构。这部分为什么这个问题对我来说很奇怪是这些东西不是相互排斥的!您可以使用类型实现协议,从而为它们提供协议描述的任何行为/功能。实际上,由于您的上下文清楚地表明您已经使用协议,我不得不怀疑 您是如何使用它们的 。我的 guess 就是你一直在使用它们记录(或者可能会对它们进行修改),但你可以很容易地将协议和(def)类型一起使用。

所以对我来说,似乎你已经把苹果与橘子比较了。为了帮助澄清,让我将苹果,苹果和橙子与橙子进行比较,并提出几个不同的问题:

协议解决了哪些问题,有哪些替代方案及其各自的优缺点?

协议允许您定义在不同类型上以不同方式运行的功能。唯一的其他方法是多方法和简单的函数逻辑:

  • 多方法:具有非常灵活的价值。您可以通过传递type作为调度函数来调度类型行为,但您也可以使用任何其他任意函数进行调度。
  • 内部函数逻辑:您当然也可以(当然)手动检查函数定义中的条件类型,以决定如何在给定不同类型的情况下进行不同的处理。这比multimethod dispatch更原始,也更不易扩展。除了简单的情况,多方法是首选。

协议具有更高性能的优势,基于JVM类/方法调度,它已经过高度优化。此外,协议旨在解决expression problem(精彩阅读),这使它们成为制作漂亮,模块化,可扩展API的强大工具。

(def)记录的优点/缺点是什么?(def)类型有什么优点/缺点?

关于我们如何指定数据结构,我们提供了许多选项:

  • (def)记录:为"生成一个类型的商品,代表应用程序域信息" (来自http://clojure.org/datatypes;值得一读)
  • (def)类型:生成较轻的类型,用于创建实现/编程域"的工件,例如标准集合类型
  • reify:使用实现一个或多个协议的匿名类型构造一次性对象;适合......需要实施协议的一次性事项

实际上,记录的行为类似于clojure哈希映射,但具有能够实现协议和更快的属性查找的额外好处。方便地,通过assoc保持可扩展性,尽管以这种方式添加的属性不共享编译的查找性能。这使得这些构造便于实现applciation逻辑。使用deftype对于实现/编程领域的方面是有利的,因为它们不会实现多余的包装,使得这些用例的使用更清晰。

答案 1 :(得分:0)

协议创建接口和接口是一个很好的接口,类型。他们描述了一种类型的某些方面,虽然没有你在Haskell这样的语言中所期望的那么严格。

答案 2 :(得分:0)

  • 机器检查
  • 类型推断(您没有从其他人的文档中获得某些协议)
  • 参数多态(参数化协议/协议与泛型不存在)
  • 高阶协议(返回协议的函数的协议是什么?)
  • 自动生成代码/样板
  • 与自动化工具的互操作