了解clojure的宏(macro)之后,真真是个好东西呀。让你可以随心所欲,设计自己的语法,甚至创造新的语言。而且clojure本身也是通过macro把很少几个语法单元组合,构建出来的。有自我生长的特点。
clojure alchemy(炼金术), 所谓点石成金,这里的石头是text(文本),而金子是求值的结果。
下面将描述整个点石成金的过程:
step 1: Reader把text(用clojure里的说法说是,reader forms)读出并转成clojure data structures
step 2: Evaluator把clojure data structures求值
clojure data structures有个鲜明的特点: 是用lists来表达的。
2. Reader:
是text(reader forms)和internal data structures的桥梁
函数read-string,可以让你看到text被转化成的data structures是什么样的(在被evaluted之前)。
3. Reader Macro:
Reader macro和macros还是两个不同的东西
user=> (read-string "#(+ 1 %)")
(fn* [p1__778#] (+ 1 p1__778#))
Reader是专为特殊符号设计的比如:' # @ 之类的。
4.Evaluation:
4.2 Symbols:
symbol会被resolve成special form或者value。
clojure resolve symbol的步骤:
1. 看symbol是否是一个special form,如果不是则继续
2. 试图找到local binding,如果不是则继续
3. 看有没有mapping到def定义的值上,如果没有
4. Throwing an exception.
4.3 Lists
只有两种情况,一种是empty list (), 否则call to the first element of the list.
4.4 Function Calls
比较重要的一点:函数的参数在被传入函数之前会被evaluated(而macro则不会)
4.5 Special forms
可以理解为clojure的保留字
5. Macros
macro和function不同的地方:
1. function的参数在传入之前被evaluated,macro则不会
2. function return的data structure不会被evaluated,而macro的返回会被evaluated
the process of determining the return value of a macro is called macro expansion.
可以用函数macroexpand看macro在被evaluated之前返回的data structure.