setf
定义的函数的基本差异是什么?
使用
defun
:
* (defun myfirst (l)
(car l) )
MYFIRST
* (myfirst '(A B C))
A
使用
setf
:* (setf (fdefinition 'myfirst) #'(lambda (l) (car l)))
#<FUNCTION (LAMBDA (L)) {10021B477B}>
* (myfirst '(A B C))
A
,如果是wikipedia:
通过使用DefunMacro
在符号中存储lambda表达式来创建名称函数 用不同的方式创建变量,需要使用
setf
:
funcall
我的理解是,这种类型的变量与以前的不同是不同的,因为该变量与
当多个命名空间中所述的Defun Bound Bound符号相同的名称空间中没有找到?。
首先,永远不要低估风格的重要性。 我们不仅编写代码以供计算机运行,而且更重要的是,让人们阅读。 使代码可读和对人的理解是软件开发的非常重要的方面。 第二,是的,
与
* (defvar myfirst)
MYFIRST
* (setf myfirst (lambda (l) (car l)))
#<Interpreted Function (LAMBDA (X) (+ X X)) {48035001}>
* (funcall myfirst '(A B C))
A
和
。
“小”差异是defun
还可以设置函数名称的doc字符串(实际上,取决于您的不症的工作原理,也可以使用lambda来做到这一点),并创建一个命名
defun
(在下面的宏扩展中看到),如果您愿意,您否则必须创建自己。
最大的区别是编译器“知道”有关block
的“知道”并将适当地处理。
e.g。,如果您的文件为
defun
(defun foo (x)
(+ (* x x) x 1))
(defun bar (x)
(+ (foo 1 2 x) x))
中打了错误的参数:
战争:第3..4行中的栏中:foo被称为3个论点,但需要1个
争论。
[foo是在第1..2行中定义的。
如果您用foo
代替
bar
,则编译器不太可能小心处理。而且,您可能会沿着的警告
使用以下功能但未定义: foo
您可能想检查
defun foo
在实现您的实现中的工作:
(setf (fdefinition 'foo) (lambda ...))
Clisp将其扩展到
defun
SBCL确实:
(macroexpand-1 '(defun foo (x) "doc" (print x)))
这里的意义是(LET NIL (SYSTEM::REMOVE-OLD-DEFINITIONS 'FOO)
(SYSTEM::EVAL-WHEN-COMPILE
(SYSTEM::C-DEFUN 'FOO (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(X))))
(SYSTEM::%PUTD 'FOO
(FUNCTION FOO
(LAMBDA (X) "doc" (DECLARE (SYSTEM::IN-DEFUN FOO)) (BLOCK FOO (PRINT X)))))
(EVAL-WHEN (EVAL)
(SYSTEM::%PUT 'FOO 'SYSTEM::DEFINITION
(CONS '(DEFUN FOO (X) "doc" (PRINT X)) (THE-ENVIRONMENT))))
'FOO)
有很多“引擎盖下”,这是出于某种原因。另一方面,更多的是“您看到的是您得到的东西”,即不涉及魔法。在现代LISP代码库中没有地位。您可以使用它,例如,实施“穷人的这并不意味着
(PROGN (EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN 'FOO NIL T)) (SB-IMPL::%DEFUN 'FOO (SB-INT:NAMED-LAMBDA FOO (X) "doc" (BLOCK FOO (PRINT X))) (SB-C:SOURCE-LOCATION)))
defun
”(未经测试):
setf fdefinition