Clojure 中的类型系统

Type system in Clojure

Clojure 中的"programming to abstractions" 原理和duck typing 一样吗?如果不是,有什么区别?

引用自http://www.braveclojure.com/core-functions-in-depth/

The reason is that Clojure defines map and reduce functions in terms of the sequence abstraction, not in terms of specific data structures. As long as a data structure responds to the core sequence operations (the functions first, rest, and cons, which we’ll look at more closely in a moment), it will work with map, reduce, and oodles of other sequence functions for free. This is what Clojurists mean by programming to abstractions, and it’s a central tenet of Clojure philosophy.

I think of abstractions as named collections of operations. If you can perform all of an abstraction’s operations on an object, then that object is an instance of the abstraction. I think this way even outside of programming. For example, the battery abstraction includes the operation “connect a conducting medium to its anode and cathode,” and the operation’s output is electrical current. It doesn’t matter if the battery is made out of lithium or out of potatoes. It’s a battery as long as it responds to the set of operations that define battery.

数据类型被行为识别为抽象 class 的一部分 ("responds to")。这不就是duck typing的精髓吗?感谢您的输入。

Data types are identified to be part of the abstract class by behaviour ("responds to").

不过他们不是。在 JVM 上,如果类型明确声明它们实现了接口,然后实现了它的方法,那么它们只能是接口的一部分。仅仅实现适当命名的方法是不够的,例如 Python,一种典型的鸭子类型语言。

写的并不完全错误,但需要一些特定的观点才能将其解释为正确的:您必须意识到作者在写作时,

As long as a data structure responds to the core sequence operations...

这意味着该类型必须实现核心序列接口及其方法。在某种程度上,仅公开一个名为 first 的函数 不足以 "respond" 同名核心序列操作:该类型还必须实现正确的接口为了"respond"。这是一种在 VM 中编写内容的奇怪方式,它不是根据消息响应来构建的,需要一些专业知识和眯眼才能找到正确的含义,但对于不需要了解的初学者来说,这是一种合理的简化详细信息......除非他们倾向于向 Stack Overflow 询问有关鸭子打字的问题!

Is the "programming to abstractions" principle in Clojure the same as duck typing?

  • Clojure 是根据 Extensible Abstractions.
  • 定义的
  • 这些是 Java 接口 ...
  • ...最突出地用于定义核心数据 结构。

例如序列抽象定义为clojure.lang.ISeq:

public interface ISeq extends IPersistentCollection {
  Object first();
  ISeq next();
  ISeq more();
  ISeq cons(Object o);
}

任何实现 ISeq 的 class 都被 Clojure 接受为一个序列(它的行为是否正确是另一回事)。例如,列表和惰性序列就是这样做的,并且被公正地视为序列。将此与 classic Lisp 进行对比,其中一组不同的函数适用于每个。

我们有几种不同的矢量实现方式

  • 核心clojure向量类型;
  • rrb 向量;
  • 快速小向量。

我可以继续。 (其实我不会,我知道的还不够多!)