我想了解有关lisp宏的更多信息,我想创建一个defun
宏的简单实现。
我也对所有实现中的lisp源代码感兴趣。
答案 0 :(得分:8)
这是一个棘手的问题,因为bootstrapping:defun
做了很多事情(喵,调用很多函数),但要定义那些函数需要有效{{1} }。因此,clisp/src/init.lisp中有defun
的三个(3!)定义:在行
defun的基本定义可能是:
defun
事实上,这是CLISP中(defmacro defun (fname lambda-list &rest body)
`(setf (fdefinition ',fname)
(lambda ,lambda-list
(block ,fname ,@body))))
的第一个定义(第228行),除了当时没有defmacro
且没有backquote 但是,所以实际的代码看起来很丑陋。
另请参阅Is defun or setf preferred for creating function definitions in common lisp and why?我在哪里讨论defun
s的宏扩展。
答案 1 :(得分: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
并按Enter键。然后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 symbol-function
来实现lambda的大部分内容。 E.g:
(setf (symbol-function 'ADD3) #'(lambda (x) (+ x 3)))
; => #<FUNCTION (LAMBDA (X)) {1006E94EBB}>
(add3 4)
; => 7