(defmacro and
([] true)
([x] x)
([x & rest]
`(let [and# ~x]
(if and# (and ~@rest) and#))))
Clojure 是 Lisp 語言家族的一員。Lisp 的許多特色已融入其他語言,但 Lisp 的程式碼即資料方法及其 巨集系統 仍使其獨樹一格。Clojure 將程式碼即資料系統擴展到括號列表 (s 表達式) 之外的向量和映射。因此,向量和映射可用於巨集語法,具有文字讀取器表示法等。
Lisp 資料,因此 Lisp 程式碼,是由 讀取器 讀取的。讀取的結果是由形式表示的資料結構。Clojure 可以編譯表示程式碼的資料結構,並在該過程中尋找對巨集的呼叫。當它看到一個呼叫時,它會呼叫巨集,將形式本身作為引數傳遞,然後使用巨集的回傳值取代巨集本身。因此,巨集是在編譯時呼叫的函式,用於執行程式碼轉換。由於程式碼即資料,因此所有 Clojure 函式庫都可用於協助轉換。因此,巨集允許 Lisp 和 Clojure 支援語法抽象。您使用巨集的原因與使用函式相同 - 消除程式碼中的重複。巨集應保留在函式不足的情況下使用,例如當您需要控制評估、產生識別碼等。Clojure 的許多核心建構不是內建的基元,而是巨集,就像使用者可以定義的一樣。以下是 and
(defmacro and
([] true)
([x] x)
([x & rest]
`(let [and# ~x]
(if and# (and ~@rest) and#))))
請注意語法引號 (` 的用法,它可以輕鬆定義巨集,其形式模擬它們產生的形式。