使用Defun和SETF定义的函数的基本差异是什么? 使用Defun: *(Defun myfirst(...

问题描述 投票:0回答:1
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

macros lisp common-lisp
1个回答
6
投票

“小”差异是

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)
有很多“引擎盖下”,这是出于某种原因。另一方面,更多的是“您看到的是您得到的东西”,即不涉及魔法。

这并不意味着

(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)))
在现代LISP代码库中没有地位。您可以使用它,例如,实施“穷人的

defun
”(未经测试):

setf fdefinition
    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.