Spec-Zone.ru › Elisp

Косвенное применение функции символа

Если первый элемент списка является символом, то оценка проверяет ячейку функции символа и использует ее содержимое вместо исходного символа. Если содержимое является другим символом, этот процесс, называемый косвенным применением функции символа, повторяется до тех пор, пока не будет получен несимвол. См. Имена функций для получения дополнительной информации о косвенном применении функции символа.

Возможным следствием этого процесса является бесконечный цикл в случае, если ячейка функции символа ссылается на тот же символ. В противном случае мы в конечном итоге получим несимвол, который должен быть функцией или другим подходящим объектом.

Более точно, у нас должна быть функция Lisp (лямбда-выражение), функция байткода, примитивная функция, макрос Lisp, специальная форма или объект автозагрузки. Каждый из этих типов описывается в одном из следующих разделов. Если объект не является одним из этих типов, Emacs сигнализирует об ошибке invalid-function.

Следующий пример иллюстрирует процесс косвенного применения символа. Мы используем fset для задания ячейки функции символа и symbol-function для получения содержимого ячейки функции (см. Ячейки функций). В частности, мы сохраняем символ car в ячейку функции first, а символ first в ячейку функции erste.

;; Build this function cell linkage:
;;   -------------       -----        -------        -------
;;  | #<subr car> | <-- | car |  <-- | first |  <-- | erste |
;;   -------------       -----        -------        -------
(symbol-function 'car)
     ⇒ #<subr car>
(fset 'first 'car)
     ⇒ car
(fset 'erste 'first)
     ⇒ first
(erste '(1 2 3))   ; Call the function referenced by erste.
     ⇒ 1

В противоположность этому, в следующем примере вызывается функция без косвенного применения функции символа, поскольку первый элемент является анонимной функцией Lisp, а не символом.

((lambda (arg) (erste arg))
 '(1 2 3))
     ⇒ 1

Выполнение самой функции оценивает ее тело; это подразумевает косвенное применение функции символа при вызове erste.

Эта форма редко используется и теперь устарела. Вместо этого вы должны написать ее как:

(funcall (lambda (arg) (erste arg))
         '(1 2 3))

или просто

(let ((arg '(1 2 3))) (erste arg))

Встроенная функция indirect-function предоставляет простой способ явного выполнения косвенного применения функции символа.

Функция: indirect-function function &optional noerror

Эта функция возвращает значение function как функцию. Если function является символом, то она находит определение функции function и начинает заново с этим значением. Если function не является символом, то она возвращает сам function.

Эта функция возвращает nil, если конечный символ не определен. Она сигнализирует об ошибке cyclic-function-indirection, если в цепочке символов есть цикл.

Необязательный аргумент noerror устарел, сохраняется для обратной совместимости и не оказывает никакого влияния.

Вот как вы могли бы определить indirect-function на языке Lisp:

(defun indirect-function (function)
  (if (and function
           (symbolp function))
      (indirect-function (symbol-function function))
    function))

Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Indirection.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API