了解clojure的宏(macro)之后,真真是個好東西呀。讓你可以隨心所欲,設計自己的語法,甚至創(chuàng)造新的語言。而且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的橋梁
函數(shù)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,如果不是則繼續(xù)
2. 試圖找到local binding,如果不是則繼續(xù)
3. 看有沒有mapping到def定義的值上,如果沒有
4. Throwing an exception.
4.3 Lists
只有兩種情況,一種是empty list (), 否則call to the first element of the list.
4.4 Function Calls
比較重要的一點:函數(shù)的參數(shù)在被傳入函數(shù)之前會被evaluated(而macro則不會)
4.5 Special forms
可以理解為clojure的保留字
5. Macros
macro和function不同的地方:
1. function的參數(shù)在傳入之前被evaluated,macro則不會
2. function return的data structure不會被evaluated,而macro的返回會被evaluated
the process of determining the return value of a macro is called macro expansion.
可以用函數(shù)macroexpand看macro在被evaluated之前返回的data structure.