在clojurescript中使用clojure代码的规范方法

时间:2016-12-14 17:41:52

标签: clojure macros clojurescript

在撰写本文时,CLJX已在Clojure / Clojurescript中解散,已被CLJC取代,因此this question不再有任何有用的答案。

所以这里是一个规范问题:你如何在同一个项目的ClojureScript中使用Clojure代码?

到目前为止,根据我的研究,我的印象是有三种类型的Clojure / Clojurescript文件:

  • CLJ:Pure Clojure
  • CLJC:“有条件地”Clojure / ClojureScript
  • CLJS:Pure Clojurescript

此外,CLJS呼叫有two ways of bringing in Clojure code

  • 预先计算的宏
  • 读者条件

这些“方法”是这样做的吗?这些在CLJ / CLJS方面看起来如何?

2 个答案:

答案 0 :(得分:3)

这基本上是正确的。如果您的代码位于.cljc文件中,则只需要该命名空间并在.cljs文件中正常使用这些函数(就像它是.cljs文件一样)。如果.cljc具有clj / cljs差异,那么可以使用.cljc文件中的reader条件对它们进行编码。

或者您可以在.clj文件中定义宏,然后从.cljs文件中请求并调用它。

答案 1 :(得分:0)

这不是真的和答案。我打算把它放在评论中,但它太长了。我认为你的动机很好,但我不确定术语。谈论在clojurescript中使用clojure代码是没有意义的。有语言,clojure,lisp的方言。它有不同的实现。在Java和JVM之上实现的'原始',一个在Javascript之上实现,一个在CLR(和其他)之上实现。所有这些代码都是clojure(方言)。

当您拥有在不同平台上实施的语言时,您将获得一些平台差异。一个常见的例子是将字符串转换为整数。在基于JVM的clojure中,您使用Java Integer对象来解析字符串并返回整数对象。在Javascript平台上,您调用标准的javascript(js)方法parsInt。

如果您只想编写一个可以在两个平台上运行的函数,您可以将其放入cljc文件中并使用reader条件来隔离函数中的平台差异。你的colure和你的clojurescript都会加载那个cljc文件,两者最终会得到一个具有相同名称和api的函数。

然而,平台之间还存在许多其他更微妙的不一致。例如,并发原语和扩展协议等等。

实际情况是,你无法在clojurescirpt中运行clojure代码。但是,由于方言中的共享语法,您可以使用clojure cocde和clojurescript代码“看起来”相同并且可以在任一方言下编译和运行。

当编写同时使用clojure和clojurescript的proram时,当你的代码看起来相同时,你真的不想写两次,你当然不希望被强制维护两个版本。在可能的情况下,您需要一个可以包含在clojure和clojurescript中的版本。一个常见的例子是数据验证库。您希望为服务器和clent使用相同的验证代码,并且您只想维护一组源。

在这个阶段,我认为最简单的方法是在cljc文件中包含该公共代码,即使defn不包含任何读者条件。但是,您仍然希望将其保持在最低限度 - 仅需要在两者之间共享的定义。

这个概念不是你在clojurescript中运行的clojure代码 - 你不能这样做。你正在做的是使用clojure方言定义代码并将其放在带有cljc扩展名的文件中,clojure和clojurescript构建过程都可以包含它。代码将被编译为JVM字节码和javascript,并且将在任一环境中运行。

一个小的复杂功能是使用ClojureScript宏。在clojureScript中,与clojure不同,宏必须位于不同的编译“单元”中,这意味着它们必须与您的其他ClojureScript代码位于不同的文件中。这是因为它们首先被扩展。它们可以位于相同的命名空间中,因此您可以使用mycode.cljs和mycode.cljc。您不能将正常的ClojureScirpt代码和ClojureScript宏混合在同一个文件中,因为这意味着它位于同一个编译单元中。