2009-09-01 73 views
0

我對lisp很新,但我一直在玩它。我有幾個問題需要澄清。下面是我定義的小宏。如何根據傳入的變量調用特定的函數?

(defmacro transform (query) 
'(lambda (row) 
    (eq (nth 1 query) (nth 0 (nth 0 row))) 
) 
) 

我只是想知道如何指定功能在體內動態使用?說如果我想使用「+」或「 - 」功能而不是「eq」,或者甚至是我定義的另一個功能?就像我認爲可以將函數的名稱作爲參數傳遞,但顯然不起作用。當我修改傳入的列表(查詢)時,我也會得到可變的未綁定錯誤。

+1

你有什麼想法,爲什麼這應該是一個宏而不是一個函數? – 2009-09-01 11:43:02

+0

我已經將它改回到一個函數,它似乎工作正常。 – 2009-09-01 12:12:36

回答

0

funcall是答案!決定只是通過它並使用funcall來評估功能。

2

在宏的主體中,您可以使用Lisp的所有運行時庫來生成實際的擴展。因此,例如:

(defmacro transform (query &key (test 'eq)) 
    (let ((row-var (gensym))) 
    `(lambda (,row-var) 
     (,test (nth 1 ,query) (nth 0 (nth 0 ,row-var)))))) 

這個版本使用「反引號」,而不是一個普通的撇號,這允許體內形式「unquoting」,從而允許夾雜物生成的表單到結果。

您可以使用此宏像你原來的版本:

(transform (...)) 

或(傳遞一個明確的測試功能):

(transform (...) :test equal) 

注意,你不應該用簡單的符號來表示與變量名宏擴展(因爲您的參數生成的lambda表達式),因爲這可能會意外地干擾在使用您的macr時使用該符號O操作。你根本不知道什麼時候寫你的宏,是否會有一個變量叫做某處,當你的宏被使用時,以及它是否已經在查詢表單/表達式中使用過。您的原始定義將「捕捉」變量,可能會改變任何查詢的含義。

相關問題