“部分应用”的定义在Emacs 24中如何工作?
“部分应用”的定义在Emacs 24中如何工作?,emacs,closures,elisp,Emacs,Closures,Elisp,部分应用的Emacs代码如下: (defun apply-partially (fun &rest args) "Return a function that is a partial application of FUN to ARGS. ARGS is a list of the first N arguments to pass to FUN. The result is a new function which does the same as FUN, except tha
部分应用的Emacs代码如下:
(defun apply-partially (fun &rest args)
"Return a function that is a partial application of FUN to ARGS.
ARGS is a list of the first N arguments to pass to FUN.
The result is a new function which does the same as FUN, except that
the first N arguments are fixed at the values with which this function
was called."
`(closure (t) (&rest args)
(apply ',fun ,@(mapcar (lambda (arg) `',arg) args) args)))
它返回一个看起来很像lambda表达式的列表,只是lambda
被closure(t)
替换。例如,(部分应用“cons 1)
返回以下内容:
(closure (t) (&rest args) (apply (quote cons) (quote 1) args))
据我所知,它的外观和工作原理与此完全相同:
(lambda (&rest args) (apply (quote cons) (quote 1) args))
除了“closure”表达式没有lambda的“self-quoting”属性之外,因此当我尝试对其求值时,Emacs通知我closure
没有函数定义:Lisp error:(void function closure)
我在Elisp手册中找不到任何关于以这种方式使用符号closure
的参考。这看起来像是某种内部Emacs魔法。显然,闭包表达式没有按照正常规则进行求值(因为手动这样做会产生错误)
这是怎么回事?我是否需要在C代码中添加对“closure”的引用才能找到答案
编辑:在Emacs 23及以下版本中,apply partially
似乎只是使用cl包中的词法let
来完成一个闭包。上面的定义来自版本“24.0.90.1”。和我的“GNU Emacs 23.2.1(i686 pc cygwin)”一起定义为
(defun apply-partially (fun &rest args)
"Return a function that is a partial application of FUN to ARGS.
ARGS is a list of the first N arguments to pass to FUN.
The result is a new function which does the same as FUN, except that
the first N arguments are fixed at the values with which this function
was called."
(lexical-let ((fun fun) (args1 args))
(lambda (&rest args2) (apply fun (append args1 args2)))))
理解它是如何工作的似乎很容易:lambda在调用原始函数时会记住部分参数集,并附加其余的参数集 我在eval.c
的funcall\u lambda
函数中找到了答案:
if (EQ (XCAR (fun), Qclosure))
{
fun = XCDR (fun); /* Drop `closure'. */
lexenv = XCAR (fun);
CHECK_LIST_CONS (fun, fun);
}
else
lexenv = Qnil;
closure(t)
似乎是lambda
的词汇等价物。第二个元素,(t)
,被分配给lexev
,所以我猜这个元素是用来结束函数本身或其他外部定义的词法值
我怀疑缺乏自我引用可能是一种疏忽,可以通过以下方式进行补救:
(defmacro make-self-quoting (name)
"Make NAME into a self-quoting function like `lambda'."
`(defmacro ,name (&rest cdr)
(list 'function (cons ',name cdr))))
(make-self-quoting closure)
我正在运行Emacs24,它现在有自己的词法范围,不依赖cl包。我猜closure
对Emacs24来说是新事物。如果它closure
是一个符号,那么apropos一定有什么东西?有一个defmacro closure
,但不清楚它是否是Emacs的一部分。不,文档中没有提到符号“closure”。它从不直接从任何elisp代码中使用,只从C代码中使用,因此在某种意义上它是Emacs内部的一部分。对,在部分应用的情况下,词法环境是空的,但仍然有一个区别:args
参数将是词法绑定的,而使用lambda
则是动态绑定的。这确保了名称args
不会干扰该变量在其他地方的其他使用。至于缺少自引用,这实际上不是一个疏忽,根本不需要:(闭包…
)不应该出现在源代码中。