2011-09-13 73 views
1

如以下Lisp代碼所示,如何理解Lisp中宏定義中的參數綁定?

(defvar a 1) 
(defvar b 2) 

(defmacro macro-add (c d) 
    `(+ ,c ,d)) 

(macro-add a b) 

它調用宏最後一行結合宏參數c來傳遞,這確實意味着c爲綁定到該符號的或結合的,其是界值以符號?更具體地說,c會在宏觀環境中評估爲a或1嗎?

+2

宏是詞法替換,因此c將被a和d替換爲b。 –

+6

使用函數'macroexpand'和'macroexpand-1'可能會幫助您瞭解宏如何工作以及它們擴展到的內容。 – Hugh

回答

3

它被綁定到符號'a'。基本上不評估宏的參數,與評估它們的函數相反。

4

宏基本上是代碼變換器。他們將代碼作爲輸入,解構並綁定到宏參數。他們使用任意計算產生新的代碼。對於簡單的類似於模板的代碼生成,反引用列表很受歡迎。

Lisp中的源代碼有兩種不同的外觀:文本s表達式和所謂的形式,它們已經是Lisp數據。這種轉變由Lisp 讀者完成。

然後對這些Lisp表單進行宏轉換。這種轉變的結果是一種新形式。最終,在擴展所有宏之後,將對結果源代碼進行評估。這幅圖有些不對,但它有助於設想有三個獨立的階段:閱讀,宏觀擴張,執行。

在你的情況下,源代碼是三個符號的列表:(macro-add a b)。第一個符號命名一個宏,所以表單將被宏擴展。該列表被解構:第一個符號是宏名稱,第二個符號將綁定到C,第三個符號將綁定到D。有了這個參數,宏現在可以執行了。結果它產生了一個新的表格:一個三個項目的列表。第一項是符號+,第二項是值C,符號A,第三項是值爲D,符號B(+ A B)是宏觀擴張的結果。

如果需要,宏展開的結果現在將再次宏展開。由於代碼中的+不是宏,因此不會進行宏擴展。 +是一個函數。現在進行普通評估:計算A的值,計算B的值,然後用這兩個值調用+來計算新的結果值。

+0

感謝您的解釋。在你的回答中,下面的句子仍然有點混淆。 1.「第二個符號將被綁定到C」,這是否意味着符號C將在宏上下文中具有值A(第二個參數)? 2.宏體'〜(+,C,D)'也有點奇怪,爲什麼不用'(+ C D)'如果宏擴展只是形式替換?讀者宏不應該評估宏觀主體,對吧?那爲什麼它仍然需要引用? – Thomson