2017-02-26 41 views
3

我想了解更多關於lisp宏的信息,我想創建一個簡單的defun宏實現。 我也對所有實現中的lisp源代碼感興趣。在lisp中如何實施defun宏?

+5

爲什麼不自己檢查一下,然後問具體問題?你可以學習許多開源的Lisp實現。如果你想了解Lisp宏,我會推薦'On Lisp' - 這本書的免費PDF:http://www.paulgraham.com/onlisp.html –

+1

起初我不知道在哪裏搜索。 – Metonymy

回答

6

這是一個棘手的問題,因爲bootstrappingdefun做了很多事情(督察,調用了大量的功能),但是定義一個需要工作defun這些功能。因此,也有在clisp/src/init.lispdefun三(3!)定義:在線路

  1. 228
  2. 1789
  3. 1946

defun定義的非常基本的定義是這樣的:

(defmacro defun (fname lambda-list &rest body) 
    `(setf (fdefinition ',fname) 
     (lambda ,lambda-list 
      (block ,fname ,@body)))) 

實際上,這是CLISP(第228行)中defun的第一個定義,除了當時沒有defmacro並且沒有backquote還有,所以實際的代碼看起來比較醜。

另請參見Is defun or setf preferred for creating function definitions in common lisp and why?其中我討論了defun s的宏觀展開。

0

可以輕鬆地查看如何您的特定CL的實施,實現defun運行

(macroexpand '(defun add2 (x) (+ x 2))) 

SBCL它擴展爲:

(PROGN 
    (EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN 'ADD2 NIL T)) 
    (SB-IMPL::%DEFUN 'ADD2 
        (SB-INT:NAMED-LAMBDA ADD2 
         (X) 
        (BLOCK ADD2 (+ X 2))) 
        (SB-C:SOURCE-LOCATION))) 
T 

要看到,實現我會使用特定的源代碼(在Emacs上)M-.鍵綁定,然後我會寫defun並回車。然後Emacs將得到源代碼:

(sb!xc:defmacro defun (&environment env name lambda-list &body body) 
    #!+sb-doc 
    "Define a function at top level." 
[...] 

我不打算粘貼整個宏,因爲它是相當長。如果您不在Emacs上,您可以嘗試在repos中搜索,因爲大多數實現都是開源的。

BTW defun並不特別。你可以用setf -inf a symbol-function來實現一個lambda。例如: -

(setf (symbol-function 'ADD3) #'(lambda (x) (+ x 3))) 
; => #<FUNCTION (LAMBDA (X)) {1006E94EBB}> 
(add3 4) 
; => 7