目前,我有一个完全功能的Clojure库,它是从Java调用的.
我这样做的方式:我有一个文件,它使用gen-class将整个API包装为单个类的静态方法,并以IPersistentVector和IPersistentMap的形式传入和传出数据.
然而,现在,我正在重构库并将功能置于各种协议之后.
我有四个协议,我们称之为A,B,C和D.两个defrecords,X和Y.X和Y都实现协议A,B和C.而Y也实现D.
我需要做些什么才能使这些可用于Java?这些是否自动作为接口和类?或者我仍然必须做相当于gen-class的公开?
如果没有,什么是gen-class:methods子句的等价物,我在哪里定义方法参数的Java类型?
有没有人有一个简单的例子可以让Java的协议和记录可用?
这是关于Clojure与其他语言(如Haskell)的表现力的问题.更广泛的问题是表达问题的解决方案
这个问题得出的结论是,一般来说Clojure协议(和多方法)的表达力要低于Haskell类型类,因为协议在第一个参数上调度,而Haskell类型类可以在返回类型上调度.(现在我认为这种推理非常有趣,并且没有兴趣开始语言大战.我只是对思想的清晰度感兴趣).
作为打破这种推理的一部分 - 我的问题是 - 我们不能制作一个Clojure多方法来调度返回类型(或类型提示).我想我们可以将以下表达式放入Clojure多方法中:
(= java.lang.String (:tag (meta #'my-string)))
Run Code Online (Sandbox Code Playgroud)
功能是:
(defn ^String my-string []
"hello world")
Run Code Online (Sandbox Code Playgroud)
编辑:关键是我可以运行:
(meta #'my-string)
Run Code Online (Sandbox Code Playgroud)
并在没有功能评估的情况下获得以下结果:
{:arglists ([]), :ns #<Namespace push-price.core>, :name my-string, :column 1,
:line 1, :file "/private/var/folders/0l/x6hr0t1j2hvcmm_sqq04vdym0000gn/T/form-
init7576840885484540032.clj", :tag java.lang.String}
Run Code Online (Sandbox Code Playgroud)
即我没有评估我的功能的预期类型的一些信息.
编辑3(2014年4月24日):
假设我有以下类型:(deftype string-type [])
(deftype int-type [])
Run Code Online (Sandbox Code Playgroud)
然后我根据这些类型定义了以下函数:
(defn #^{:return-type string-type} return-string []
"I am returning a string")
(defn #^{:return-type int-type} return-int []
42)
Run Code Online (Sandbox Code Playgroud)
现在我编写一个函数来调度它们的返回类型,如下所示:
(defn return-type-dispatch [fn-arg]
(let [return-type (:return-type (meta fn-arg))]
(cond
(= return-type …Run Code Online (Sandbox Code Playgroud) 似乎Clojure编译器默认不执行此操作:Clojure编译器是否检查记录和类型是否实现协议?
任何,比方说,Lein插件这样做?