2014-01-19 20 views
3

CLHSsymbol-macrolet句柄如何實現陰影效果?

符號macrolet詞法建立擴展函數對每個由符號指定的符號的宏。

...

使用符號macrolet可以通過讓被遮蔽。

這讓下面的代碼工作(* B * X內勢必爲「1」):

CT> (with-slots (x y z) *b* 
     (let ((x 10)) 
     (format nil "~a ~a ~a" x y z))) 
"10 2 3" 

我的問題是:如何符號宏讓知道哪些形式被允許影子呢?我問,宏不能保證let不被重新定義,或者用戶沒有創建另一個表單來完成與let相同的工作。這是一個特殊的'愚蠢'的情況下,只是看看CL:讓符號?還是有一些更先進的技術正在進行?

我很高興編輯這個問題,如果它太模糊,我很難闡明這個問題。

+2

我確實不確定你在問什麼,但請記住'symbol-macrolet'和'let'本身都是*特殊操作符* - 語言的構建磚塊。他們不應該被重新定義或遮蔽,否則就會發生混亂。 –

+1

是的,我想知道讓事實是否特別與這是如何做有關。看過Ben的回答後,我瞭解到宏可以獲得關於他們所處的詞彙環境的信息,這些環境非常有趣並且可能是相關的......我需要閱讀! – Baggers

回答

3

正如您所見,SYMBOL-MACROLET是Common Lisp的一項內置功能。就像LET一樣。這些特殊運營商不能重新定義,也不允許這樣做。

Common Lisp只有一組固定的特殊操作符,無法由用戶定義。只有這些定義:Common Lisp special operators

由於宏將被擴展,它們擴展到基本原語:函數調用和特殊形式。因此,編譯器/解釋器實現了符號 - 宏單元,並且這個任務受限於原始形式的數量。如果用戶實現他/她自己的LET,那麼最終這個實現也可以歸結爲函數調用和特殊形式 - 宏的所有用法將最終擴展到那些。但是這些都是已知的,並沒有什麼新的符號宏。

4

見3.1.1.4和周圍的材料。

從哪裏來的報價?我不認爲這是完全正確的,因爲讓我們不是唯一能夠在詞彙環境中隱藏由macrolet建立的名字的東西。

我認爲,揭示詞彙環境不僅僅是一個抽象的概念會有很大的危害,還有一個實際的數據結構體現了它。詞彙環境在編譯時通過環境綁定機制可用於宏。宏可以使用它來獲得一個窗口進入環境,並有一個使用該環境的協議。因此,舉一個簡單的例子,可以編寫對詞彙環境中的聲明敏感的宏,例如,如果聲明瞭一個變量fixnum,則擴展一種方法。

環境的實施由實施者決定,但是這只是堆疊名稱和名稱信息。所以,lambda綁定,小標籤,標籤,let *等等只是將新名稱推入堆棧,從而隱藏舊名稱。詞彙聲明增加了有關名稱的信息。

編譯器或評估程序然後使用環境(堆棧)來指導結果代碼或執行的行爲。值得注意的是,這個數據結構不需要存在運行時,儘管通常它的一些後代可以幫助調試器。

因此,要回答你的問題:macrolet不知道什麼形式的&身體可能正在做什麼。

+0

引用的文本來自我在問題頂部鏈接的hyperspec頁面,但示例代碼是我的。儘管我對環境一無所知,但是非常感謝你,不知道我是如何錯過的,但我確實需要給予閱讀! – Baggers