2

これで、厳密に言えば、 Clojure プロトコルでのディスパッチが動的であることがわかりました。

マクロを使用したコンパイル時のディスパッチの素晴らしい例を次に示します。

(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))))

ここで筆者は、Clojure では戻り型でディスパッチすることは決してできないと主張しています。私には、十分に強力なマクロがあれば、何でもできるように思えます。

私の質問は、マクロを使用して、Clojure で戻り値の型を静的にディスパッチできますか?

4

1 に答える 1

1

理論的には、マクロを使用して Haskell の型セマンティクスを使用して Clojure DSL を構築できるため、厳密に言えばそれは可能です。

ただし、実用的な観点からは、コンパイル時に戻り値の型をディスパッチするということは、この情報を利用可能にしてコンパイル時に伝播することを意味します。Clojure には組み込みの「戻り値の型」がありません (すべての関数は可変数のオブジェクト型の引数を受け入れ、オブジェクトを返します)。そのため、おそらく独自の型システムを展開し、プログラムの大部分をマクロを使用するとすぐに型分析が利用可能でなければならないという制約付きで( Type Clojureのように)参加します。

(しゃれを意図した)の場合はcase+、型システムを必要としないため異なります。ほとんどの場合、評価順序の問題です。

于 2016-07-11T12:07:28.633 に答える