Код 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)))
Он возвращает список, который очень похож на лямбда-выражение, за исключением того, что лямбда
заменена на closure (t)
. Например, (apply-partially 'cons 1)
возвращает следующее:
(closure (t) (&rest args) (apply (quote cons) (quote 1) args))
которое, насколько я могу судить, выглядит и работает точно так же, как следующее:
(lambda (&rest args) (apply (quote cons) (quote 1) args))
за исключением того, что выражение "closure" не обладает свойством "самоцитирования" лямбды, поэтому, когда я пытаюсь его оценить, Emacs сообщает мне, что closure
не имеет определения функции: Lisp error: (void-function closure)
.
Я не могу найти в руководстве по Elisp никаких ссылок на использование символа closure
таким образом. Это похоже на какую-то внутреннюю магию Emacs. Выражение закрытия явно не оценивается в соответствии с обычными правилами (поскольку выполнение этого действия вручную приводит к ошибке).
Так что же здесь происходит? Нужно ли мне искать в коде C ссылки на "закрытие", чтобы выяснить это?
EDIT: Оказывается, в Emacs 23 и ниже apply-partially
просто использует lexical-let
из пакета cl для создания закрытия. Приведенное выше определение относится к версии "24.0.90.1".