一千萬個為什麽

搜索

Stdlib支持編譯時元編程?

以下宏...

(defmacro compile-time-eval (&rest body)
    (eval (cons 'progn body)))

...允許這樣的編譯時元編程(一個小的人為例子):

(compile-time-eval
 `(defun join-dirs (a b)
    (concat a
            ,(if (eq system-type 'windows-nt)
                 "\\"
               "/")
            b)))

類似於 compile-time-eval 標準庫的一部分嗎? ( eval-when-compile 接近,但它引用了結果。)

如果沒有,那麽實施這個例子的推薦方法是什麽?

最佳答案

宏不評估結果,它們評估為擴展,這是一種在宏寫入的位置替換宏的表單,擴展站點。編譯器不會評估擴展本身。

因此,您通常不會嘗試完全生成函數定義。相反,你會編寫一個宏來執行你想要的任何擴展,並簡單地在函數體中使用該宏,即

(defmacro my/path-separator ()
  (if (eq system-type 'windows-nt) "\\" "/"))

(defun join-dirs (a b)
  (concat a (my/path-separator) b))

但在此特定示例中,您根本不應使用宏。 Emacs的字節代碼實際上不是特定於操作系統或體系結構的,因此在擴展期間不得生成特定於系統的代碼。換句話說,路徑分隔符不是編譯時常量,它是一個加載時間常量,應該在加載時而不是在編譯時計算。

通常,您只應將宏用於語法,而從不用於語義。

實際上你只需要在這裏使用(expand-file-name“b”“a”) :)

轉載註明原文: Stdlib支持編譯時元編程?