我在互联网上搜索了答案,但没有太多运气,所以请原谅我,如果这是一个重复的问题。我将陈述我的问题:=(?)因此以及随后的代码中的注释。 (我正在使用带有clisp和Slime的Emacs):
;; is this called nested function or partial application or what(?)
(defun create-function(a)
(defun add-function(x)(+ x a)))
->(create-function 8)
->ADD-FUNCTION
->(add-function 3)
->11
我可以看到链接这些“部分应用程序”的好处,但这本身并不是正确的,对吧(?)好吧,让我们检查一下我的观察结果是否正确:
;; the 'let statement *binds* 'loc to the 'clos object with 10 being the argument
;; for the formal parameter x. when funcall is applied to 'loc with 20 for y, the
;; lambda expression substitutions are complete and 200 is returned(?).
(defun close(x)
(lambda(y)(* x y)))
->CLOSE
(let ((loc (close 10)))
(funcall loc 20))
->200
上面的代码是一个闭包(?),因为'let语句中'loc>的范围:如果'clos是一个可变变量,它只会在'let语句内部改变值(?)... 我认为。最后,如果有人能告诉我如何让step宏与上述函数配合使用,那将会有很大帮助,(他们会立即评估......)谢谢。
答案 0 :(得分:0)
第一个例子可以称为嵌套函数和部分评估。但下一个例子更具惯用性。两者都可称为手动卷曲,但通常将卷曲理解为自动程序。您可以在Lisp中使用currying(一种变体):
(defun curry (function &rest arguments)
(lambda (&rest more)
(multiple-value-call function
(values-list arguments) (values-list more))))
谈到闭包问题:funcall
下的let
不是闭包 - 闭包是let
中的函数定义。实际上,你的第一个例子是一个闭包,因为你在另一个函数中定义了一个函数,每个函数都引入了类似于let
绑定的东西。
然而,在你的案例中,一个更典型的例子是:
(let ((z 10))
(defun close (x)
(* x z))
->CLOSE
(close 20)
->200
此处,z
是在闭包中捕获的变量。
答案 1 :(得分:0)
第一个例子既不是嵌套函数也不是部分应用程序。相反,它会在每次调用外部函数时评估内部defun
,重新定义全局可见的add-function
。我不认为这种模式有任何特定的名称。
Common Lisp确实使用flet
和labels
形式的词法作用域嵌套函数。
在第二个示例中,函数close
返回一个闭包(一个函数值,它引用词法绑定在该函数体外的变量)。使用该返回值执行的操作不会影响它的值。
step
在SBCL中将毫无用处。通过将此表单放在函数之前来执行此操作:
(proclaim '(optimize (debug 3)))