首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用cljx的目标相关宏

使用cljx的目标相关宏
EN

Stack Overflow用户
提问于 2015-02-27 00:13:48
回答 2查看 103关注 0票数 3

问题描述

我有一个通过ClojureScript以CLJX为目标的项目。

我有一个宏,它接受一个thunk,并创建一个IDeref实例来在每次取消引用(使用deref@)时执行该thunk。

因为它是一个宏,所以它必须放在一个.clj文件中。问题是,对于Clojure和ClojureScript,IDeref接口是不同的。在Clojure中,我需要生成以下内容:

代码语言:javascript
复制
(reify clojure.lang.IDeref
  (deref [_] thunk))

在ClojureScript中,我需要生成以下内容:

代码语言:javascript
复制
(reify IDeref
  (-deref [_] thunk))

因为这是一个宏,所以我不能使用cljx (例如#+cljs -deref)中类似于特性表达式的语法来协调我的两个目标平台的代码。以下是我最后所做的:

代码语言:javascript
复制
(defmacro make-thunk [exp]
  `(reify ~params/IDeref-interface
     (~params/IDeref-method [_#] ~exp)))

然后,我在clj和cljs源树中都有一个单独的params.clj,每个源树对于每个所需的符号都有一个def

这很管用,但它真的很丑,感觉就像一次肮脏的黑客攻击。

我的问题

我非常希望将我的所有宏都保存在同一个名称空间中。我希望不必在单独的文件中为宏定义每个依赖于平台的符号。在两个源树中,我已经有了依赖于平台的compat.clj和compat.cljs文件。不得不添加更多的文件来支持平台相关的宏开始让人感到混乱。

这个问题有更干净的解决办法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-27 07:08:13

在宏的主体中,(:ns &env)在ClojureScript中展开时是真实的,而在Clojure中则不然。

这是目前编写特定于平台的宏的“最佳实践”:

代码语言:javascript
复制
(defmacro platform []
  (if (:ns &env)
    :CLJS
    :CLJ))
票数 3
EN

Stack Overflow用户

发布于 2015-02-27 00:48:29

这应该能起作用:

代码语言:javascript
复制
(defn compiling-cljs?
  "Returns true if we seem to be compiling ClojureScript, false otherwise.

  This is a Clojure function, meant to be called by macros targeting both
  Clojure and ClojureScript."
  []
  (if-let [cljs-ns-var (resolve 'cljs.analyzer/*cljs-ns*)]
    (some? @cljs-ns-var)
    false))

使用方式如下:

代码语言:javascript
复制
(defmacro foo []
  (if (compiling-cljs?)
    1
    2))

(我有一种感觉,这个问题以前已经解决了,但似乎找不到参考。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28755294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档