3

問題の説明

CLJXを介して Clojure (JVM) と ClojureScript の両方をターゲットとするプロジェクトがあります。

IDerefサンクを取り、それが参照解除されるたびにそのサンクを実行するインスタンスを作成するマクロがあります (derefまたはを使用@)。

これはマクロなので、.cljファイルに入れる必要があります。問題は、IDerefClojure と ClojureScript でインターフェースが異なることです。Clojure では、これを生成する必要があります。

(reify clojure.lang.IDeref
  (deref [_] thunk))

ClojureScript では、これを生成する必要があります。

(reify IDeref
  (-deref [_] thunk))

これはマクロであるため、cljx の機能式のような構文 (例: #+cljs -deref) を使用して、2 つのターゲット プラットフォームのコードを調整することはできません。これが私がやったことです:

(defmacro make-thunk [exp]
  `(reify ~params/IDeref-interface
     (~params/IDeref-method [_#] ~exp)))

次に、clj ソース ツリーと cljs ソース ツリーの両方に別のparams.cljdefを用意します。それぞれのツリーには、必要なシンボルごとに for があります。

これは機能しますが、非常に見苦しく、汚いハックのように感じます。

私の質問

すべてのマクロを同じ名前空間に保持したいと考えています。マクロ用のすべてのプラットフォーム依存シンボルを個別のファイルで定義する必要はありません。2 つのソース ツリーに、プラットフォームに依存するcompat.cljおよびcompat.cljsファイルが既にあります。プラットフォームに依存するマクロをサポートするためにさらにファイルを追加する必要があるため、物事が雑然とし始めています。

この問題に対するよりクリーンな解決策はありますか?

4

2 に答える 2

3

マクロの本体内では、(:ns &env)ClojureScript で展開する場合は true になりますが、Clojure では展開しません。

これは現在、プラットフォーム固有のマクロを記述するための「ベスト プラクティス」です。

(defmacro platform []
  (if (:ns &env)
    :CLJS
    :CLJ))
于 2015-02-27T07:08:13.470 に答える