2017-02-26 6 views
3

Ich möchte mehr über Lisp Makros lernen, und ich möchte eine einfache Implementierung des Makros defun erstellen. Ich bin auch an Lisp Quellcode in allen Implementierungen interessiert.Wie wird das Defun-Makro in Lisp implementiert?

+5

Warum überprüfen Sie es nicht selbst und stellen Sie dann spezifische Fragen? Es gibt viele Open-Source-Lisp-Implementierungen, die Sie studieren können. Wenn Sie etwas über Lisp Makros erfahren möchten, würde ich 'On Lisp' empfehlen - kostenloses PDF des Buches: http://www.paulgraham.com/onlisp.html –

+1

Zuerst wusste ich nicht, wo ich suchen sollte. – Metonymy

Antwort

6

Dies ist eine schwierige Frage, weil die bootstrapping: defun eine Menge Dinge tut (IOW, ruft eine Vielzahl von Funktionen), aber diese Funktionen zu definieren, ein eine Arbeits defun muss. So gibt es drei (3!) Definitionen von defun in clisp/src/init.lisp: bei Linien

  1. 228
  2. 1789
  3. 1946

Die grundlegende Definition von defun dies sein könnte:

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

In der Tat ist dies die erste Definition von defun in CLISP (Zeile 228), mit der Ausnahme, dass es defmacro und backquote zu diesem Zeitpunkt noch gibt, so dass der eigentliche Code viel hässlicher aussieht.

Siehe auch Is defun or setf preferred for creating function definitions in common lisp and why?, wo ich Makroexpansion von defun s diskutieren.

0

Sie können ganz einfach überprüfen, wie Ihre spezielle Implementierung CL, implementiert defun von

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

Auf SBCL läuft es expandiert nach:

(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 

Um die besondere Quellcode zu sehen, dass die ich umgesetzt würden verwenden (auf Emacs) die M-. Schlüsselbindung und dann werde ich defun schreiben und Enter drücken. Dann wird Emacs auf den Quellcode erhalten:

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

Ich bin nicht die ganze Makro gehen einzufügen, wie es ist ziemlich lang. Wenn Sie nicht auf Emacs sind, können Sie versuchen, in den Repos zu suchen, da die meisten Implementierungen Open Source sind.

BTW defun ist nicht so besonders. Sie können viel davon mit setf-in einem symbol-function zu einem Lambda implementieren. Z.B .:

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