我非常不喜欢中文字面翻译–'宏', 中文宏的意思是大, 广大, 实在想不通这跟macro有毛关系. 而macro值的是某条指令可以扩展 成一堆其它指令. 反而用个图我觉得更贴切
(macroexpand '(when-not (= 1 3) (print "damn"))) ; => (if (= 1 3) nil (do (print "damn")))
看看Clojure的macro when-not
能扩展成什么? 神奇的变成了if.
靠, 这不是就是语法糖?
嗯, 就是语法糖, 但是是强大的可以自定义的语法糖. 这代表着你可以用Clojure编写自己独特版本的Clojure.
lisp语言因为本身的原因能轻松这么办到
如果英文好, 可以看看 这篇解释clojure macro的文章
但是就算可以自定义语法糖, 到底有什么好处呢, 真的只是使语法更好看吗?
当然不是, macro可以说是元编程的终极形态, 当Clojure推出core.async这么牛逼的库之后, 立即就被port到 ClojureScript, 也就是说, ClojureScript写的 go block 可以编译成能在浏览器上抛的单线程JavaScript.
如果回忆不起来可以翻看下如何用JavaScript实现 core.async 的 go block. 你会发现 generator 是实现的关键, 而ClojureScript却只用macro展成不同的纯状态机实现.
怎么做到的呢, 就是macro, 如果你翻看ClojureScript 的 core.async源码 , 会看见一堆一堆的macro. 根据go block 中不同的语法扩展成不一样的状态机.