如以下Lisp代碼所示,如何理解Lisp中宏定義中的參數綁定?
(defvar a 1)
(defvar b 2)
(defmacro macro-add (c d)
`(+ ,c ,d))
(macro-add a b)
它調用宏最後一行結合宏參數c來傳遞,這確實意味着c爲綁定到該符號的或結合的,其是界值以符號?更具體地說,c會在宏觀環境中評估爲a或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嗎?
它被綁定到符號'a'。基本上不評估宏的參數,與評估它們的函數相反。
宏基本上是代碼變換器。他們將代碼作爲輸入,解構並綁定到宏參數。他們使用任意計算產生新的代碼。對於簡單的類似於模板的代碼生成,反引用列表很受歡迎。
Lisp中的源代碼有兩種不同的外觀:文本s表達式和所謂的形式,它們已經是Lisp數據。這種轉變由Lisp 讀者完成。
然後對這些Lisp表單進行宏轉換。這種轉變的結果是一種新形式。最終,在擴展所有宏之後,將對結果源代碼進行評估。這幅圖有些不對,但它有助於設想有三個獨立的階段:閱讀,宏觀擴張,執行。
在你的情況下,源代碼是三個符號的列表:(macro-add a b)
。第一個符號命名一個宏,所以表單將被宏擴展。該列表被解構:第一個符號是宏名稱,第二個符號將綁定到C
,第三個符號將綁定到D
。有了這個參數,宏現在可以執行了。結果它產生了一個新的表格:一個三個項目的列表。第一項是符號+
,第二項是值C
,符號A
,第三項是值爲D
,符號B
。 (+ A B)
是宏觀擴張的結果。
如果需要,宏展開的結果現在將再次宏展開。由於代碼中的+
不是宏,因此不會進行宏擴展。 +
是一個函數。現在進行普通評估:計算A
的值,計算B
的值,然後用這兩個值調用+
來計算新的結果值。
感謝您的解釋。在你的回答中,下面的句子仍然有點混淆。 1.「第二個符號將被綁定到C」,這是否意味着符號C將在宏上下文中具有值A(第二個參數)? 2.宏體'〜(+,C,D)'也有點奇怪,爲什麼不用'(+ C D)'如果宏擴展只是形式替換?讀者宏不應該評估宏觀主體,對吧?那爲什麼它仍然需要引用? – Thomson
宏是詞法替換,因此c將被a和d替換爲b。 –
使用函數'macroexpand'和'macroexpand-1'可能會幫助您瞭解宏如何工作以及它們擴展到的內容。 – Hugh