我们可以使用宏在Clojure中对返回类型进行静态调度吗?

时间:2016-07-08 13:24:14

标签: clojure macros dispatch static-dispatch

现在我们知道Clojure Protocols的调度,strictly speaking, is dynamic

我们在这里看到compile-time dispatch使用宏的一个很棒的例子:

(defmacro case+
  "Same as case, but evaluates dispatch values, needed for referring to
   class and def'ed constants as well as java.util.Enum instances."
  [value & clauses]
  (let [clauses (partition 2 2 nil clauses)
        default (when (-> clauses last count (== 1))
                  (last clauses))
        clauses (if default (drop-last clauses) clauses)
        eval-dispatch (fn [d]
                        (if (list? d)
                          (map eval d)
                          (eval d)))]
    `(case ~value
       ~@(concat (->> clauses
                   (map #(-> % first eval-dispatch (list (second %))))
                   (mapcat identity))
           default))))

这里the writer argues你永远无法在Clojure中的返回类型上发送。{对我来说,似乎有一个足够强大的宏,你可以做任何事情。

我的问题是:我们可以使用宏在Clojure中对返回类型进行静态调度吗?

1 个答案:

答案 0 :(得分:0)

理论上,您可以使用宏来构建具有Haskell类型语义的Clojure DSL,因此严格来说,这是可能的。

但是,从实际的角度来看,在compile-type上调度返回类型意味着使这些信息可用并在编译时传播它。 Clojure中没有内置的“返回类型”(所有函数都接受可变数量的Object类型参数并返回一个Object),所以你可能不得不推出自己的类型系统并需要大部分程序来参与其中(àlaType Clojure),其约束条件是您在使用宏时必须立即使用类型分析。

case+(双关语)的情况不同,因为它不需要类型系统,它主要是评估顺序。