"应用部分"的定义如何在Emacs 24中起作用?

Rya*_*son 5 emacs closures elisp

Emacs代码apply-partially是这样的:

(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)))
Run Code Online (Sandbox Code Playgroud)

它返回一个看起来很像lambda表达式的列表,除了lambda被替换为closure (t).例如,(apply-partially 'cons 1)返回:

(closure (t) (&rest args) (apply (quote cons) (quote 1) args))
Run Code Online (Sandbox Code Playgroud)

据我所知,它的外观和作用完全如下:

(lambda (&rest args) (apply (quote cons) (quote 1) args))
Run Code Online (Sandbox Code Playgroud)

除了"闭包"表达式没有lambda的"自引用"属性,所以当我尝试评估它时,Emacs通知我closure没有函数定义:Lisp error: (void-function closure).

我在Elisp手册中找不到closure以这种方式使用符号的任何参考.它似乎是某种内部Emacs魔法.根据正常规则,闭包表达式显然没有被评估(因为手动执行该操作会产生错误).

那么这里发生了什么?我是否需要grep C代码以获取对"closure"的引用才能找到答案?

编辑:似乎在Emacs 23及以下版本中,apply-partially只需使用lexical-letcl包中的一个闭包.上面的定义来自版本"24.0.90.1".

Rya*_*son 4

eval.c我在函数中找到了答案funcall_lambda

  if (EQ (XCAR (fun), Qclosure))
{
  fun = XCDR (fun); /* Drop `closure'.  */
  lexenv = XCAR (fun);
  CHECK_LIST_CONS (fun, fun);
}
  else
lexenv = Qnil;
Run Code Online (Sandbox Code Playgroud)

closure (t)似乎是 的词汇等价物lambda。第二个元素(t)被分配给lexenv,所以我猜这个元素是为了关闭在函数本身或其他东西之外定义的词法值。

我怀疑缺乏自我引用可能是一个疏忽,可以通过以下方式纠正:

(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)
Run Code Online (Sandbox Code Playgroud)