2008-11-11 50 views
5

仍在努力理解與宏有關的最佳實踐。我正試圖編寫一個宏,它可以即時定義軟件包。Common Lisp初學者:Macro用於定義包中的軟件包的問題

(defmacro def-dynamic-package (name) 
    `(defpackage ,(intern (string-upcase name) "KEYWORD") 
    (:use :common-lisp))) 

這僅適用於表達式,如能正常工作:

(def-dynamic-package "helloworld") 

但悲慘的失敗了這樣的事情:

(defun make-package-from-path (path) 
    (def-dynamic-package (pathname-name path))) 

(defun make-package-from-path (path) 
    (let ((filename (pathname-path))) 
    (def-dynamic-package filename))) 

我瞭解最基本的宏工作,但如何執行這個逃脫我。

回答

8

defpackage是一個宏。因此,它在編譯時進行擴展,而不是在運行時進行擴展。你想要的是在運行時被調用來創建一個新的包。因此,defpackage不能爲你做任何事情。

幸運的是,這裏還有make-package,它提供defpackage的特徵函數。用它代替defpackage

0

這裏可能會出現故障,因爲不應評估其參數時使用宏。

在你第一次化妝包從路徑,在高清動態包將獲得作爲參數列表等於以下表達式的值:

(list 'pathname-name 'path) 

在你的情況,你只想要一個功能:

(defun def-dynamic-package (name) 
    (defpackage (string-upcase name) 
    (:use :common-lisp))) 

順便說一句,如果你檢查CLHS,你會看到的defpackage第一個參數不一定是一個符號,但任何string designator

+0

非常感謝,我有這樣的感覺,即學習Common Lisp對於學習何時以及何時不使用宏有很大的幫助。 – dnolen 2008-11-11 01:50:59

+0

你在那裏做的是定義一個名爲「(STRING-UPCASE NAME)」的包 - 至少如果列表是一個有效的字符串指示符,那你就是在做什麼。無論如何,你的代碼不能移植工作。 – 2008-11-11 08:02:53