Clojure China

一次失败的 ClojureScript macro 使用经历

#1

不喜欢看博客写那么长的英文 http://blog.fikesfarm.com/posts/2016-03-01-clojurescript-macro-sugar.html

大体就是 ClojureScript 的 Macro 不好实现, 最终能用, 但是跟 Clojure 的写法不一样.

Wrong. 比如 Lumo, 直接在 Clojure 里正常的代码, 在这边结果就是错的, nil 是什么鬼…

cljs.user=> (defmacro my-if [p t f] `(if ~p ~t ~f))
#'cljs.user/my-if
cljs.user=> (my-if true 1 2)
(if 2 nil nil)

Wrong. 大体上的意思是要从另一个文件载入时候才能处理掉, 我原来以为是命名空间就好了, 还是错.

cljs.user=> (ns a.b)
nil
a.b=> (defmacro my-if [p t f] `(if ~p ~t ~f))
#'a.b/my-if
a.b=> (ns cljs.user)
nil
cljs.user=> (a.b/my-if true 2 3)
(if 3 nil nil)
cljs.user=> (require-macros '[a.b :refer [my-if]])
No such macros namespace: a.b, could not locate a/b.clj or a/b.cljc
	 (new)
	 Function.cljs.core.ex_info.cljs$core$IFn$_invoke$arity$3 (NO_SOURCE_FILE <embedded>:1937:200)
	 Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$3 (NO_SOURCE_FILE <embedded>:2484:92)
	 Function.cljs.analyzer.error.cljs$core$IFn$_invoke$arity$2 (NO_SOURCE_FILE <embedded>:2483:92)
	 (NO_SOURCE_FILE <embedded>:5239:92)
	 Object.lumo.repl.load_other (NO_SOURCE_FILE <embedded>:6123:380)
	 lumo.repl.load (NO_SOURCE_FILE <embedded>:6127:106)
	 Function.cljs.js.require.cljs$core$IFn$_invoke$arity$5 (NO_SOURCE_FILE <embedded>:5229:528)
	 Object.cljs.js.load_macros (NO_SOURCE_FILE <embedded>:5270:223)
	 (NO_SOURCE_FILE <embedded>:5287:405)

Correct. 看了半天, 结果还有一个 $macros 的写法, 从来没看到过, 试了一下, 可以了.

cljs.user=> (ns foo.core$macros)
nil
foo.core$macros=> (defmacro my-if [p t f] `(if ~p ~t ~f))
#'foo.core$macros/my-if
foo.core$macros=> (ns cljs.user)
nil
cljs.user=> (foo.core/my-if true 1 2)
1

多谢 lumo 作者纠正…