問題の説明
CLJXを介して Clojure (JVM) と ClojureScript の両方をターゲットとするプロジェクトがあります。
IDeref
サンクを取り、それが参照解除されるたびにそのサンクを実行するインスタンスを作成するマクロがあります (deref
またはを使用@
)。
これはマクロなので、.cljファイルに入れる必要があります。問題は、IDeref
Clojure と 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ファイルが既にあります。プラットフォームに依存するマクロをサポートするためにさらにファイルを追加する必要があるため、物事が雑然とし始めています。
この問題に対するよりクリーンな解決策はありますか?