【问题标题】:Can we use macros to statically dispatch on a return type in Clojure?我们可以使用宏在 Clojure 中对返回类型进行静态调度吗?
【发布时间】:2016-07-08 13:24:13
【问题描述】:

现在我们知道了 Clojure 协议上的调度,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 中静态调度返回类型吗?

【问题讨论】:

  • 这个case* 宏与问题有什么关系?
  • 它在编译时生成一个构造。它是一个非运行时 Clojure 调度。

标签: clojure macros dispatch static-dispatch


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    • 2013-06-28
    • 2021-04-25
    • 1970-01-01
    • 2014-05-14
    相关资源
    最近更新 更多