标签:clojure
由于micro接收的参数可以很复杂,而且不求值,因此可以接收list,在内部转换,加工后执执行,也可以接收完全不是lisp的语法,在内部转换成clojure能执行的list。
这样可以创建自己的DSL,而把clojure宏实现为DSL解析器。
特点是允许在Clojure evaluate你的list之前,你能够像处理函数一样的处理它, 但是不evaluate。
如果你想把一个表达式作为参数传递给函数,并要求这个参数不求值,这是做不到的。比如下面的函数定义会报错:
user=> (def ignore-last-operand2 [function-call] (butlast function-call)) #_=> #_=> user=> CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(/tmp/form-init3734404425586418360.clj:1:1)
这种情况需要使用宏了。
user=> (defmacro ignore-last-operand [function-call] (butlast function-call)) #_=> #_=> #‘user/ignore-last-operand user=> (ignore-last-operand (+ 1 2 10)) 3
上面的例子中,其实经过了去除最后一个symbol,然后再对余下的list求值的过程。
(+ 1 2 10) -> (+ 1 2) -> 3
要想知道最后求值结果出来前的list,可以使用macroexpand. 注意要配合使用‘ 表示不要求值。
user=> (macroexpand ‘(ignore-last-operand (+ 1 2 10))) (+ 1 2)
(defn read-resource "Read a resource into a string" [path] (read-string (slurp (clojure.java.io/resource path))))
(defn read-resource [path] (-> path clojure.java.io/resource slurp read-string))
binding宏用来创建线程专属的变量,在多线程中很常用。
user=> (def ^:dynamic x 1) user=> (def ^:dynamic y 1) user=> (+ x y) 2 user=> (binding [x 2 y 3] (+ x y)) 5 user=> (+ x y) 2
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:clojure
原文地址:http://blog.csdn.net/csfreebird/article/details/49230131