В общем смысле функция — это правило для выполнения вычислений по заданным входным значениям, называемым аргументами. Результат вычисления называется значением или возвращаемым значением функции. Вычисление также может иметь побочные эффекты, например, постоянные изменения значений переменных или содержимого структур данных (см. Определение побочного эффекта). Чистая функция — это функция, которая, помимо отсутствия побочных эффектов, всегда возвращает одно и то же значение для одного и того же набора аргументов независимо от внешних факторов, таких как тип машины или состояние системы.
В большинстве языков программирования каждая функция имеет имя. Но в Lisp функция в строгом смысле не имеет имени: это объект, который может опционально быть связан с символом (например, car), служащим именем функции. См. Именование функции. Когда функция получила имя, мы обычно также называем этот символ «функцией» (например, мы говорим «функция car»). В данном руководстве различие между именем функции и самим объектом функции обычно неважно, но мы будем обращать на него внимание там, где это имеет значение.
Некоторые объекты, подобные функциям, называемые специальными формами и макросами, также принимают аргументы для выполнения вычислений. Однако, как объясняется ниже, они не считаются функциями в Emacs Lisp.
Вот важные термины для функций и объектов, подобных функциям:
Функция (в строгом смысле, т. е. объект функции), которая написана на Lisp. Они описаны в следующем разделе. См. Лямбда-выражения.
Функция, которая может быть вызвана из Lisp, но фактически написана на C. Примитивы также называются встроенными функциями или subr. Примеры включают функции car и append. Кроме того, все специальные формы (см. ниже) также считаются примитивами.
Обычно функция реализована как примитив, потому что она является фундаментальной частью Lisp (например, car), или потому что она предоставляет низкоуровневый интерфейс к службам операционной системы, или потому что она должна работать быстро. В отличие от функций, определенных в Lisp, примитивы могут быть изменены или добавлены только путем изменения исходников на C и перекомпиляции Emacs. См. Написание примитивов Emacs.
Примитив, который похож на функцию, но не вычисляет все свои аргументы обычным способом. Он может вычислять только некоторые аргументы, или вычислять их в необычном порядке, или несколько раз. Примеры включают if, and и while.
См. Специальные формы.
Конструкция, определенная в Lisp, которая отличается от функции тем, что преобразует выражение Lisp в другое выражение, которое должно быть вычислено вместо исходного. Макросы позволяют программистам Lisp делать то же, что могут делать специальные формы. См. Макросы.
Объект, который может быть вызван через примитив command-execute, обычно из-за того, что пользователь вводит последовательность клавиш, привязанную к этой команде. См. Интерактивный вызов. Команда обычно является функцией; если функция написана на Lisp, она превращается в команду с помощью формы interactive в определении функции (см. Определение команд). Команды, являющиеся функциями, также могут вызываться из выражений Lisp, как и другие функции.
Клавиатурные макросы (строки и векторы) также являются командами, хотя они не являются функциями. См. Клавиатурные макросы. Мы говорим, что символ является командой, если его функциональная ячейка содержит команду (см. Компоненты символа); такая именованная команда может быть вызвана с помощью M-x.
Объект функции, очень похожий на лямбда-выражение, за исключением того, что он также содержит окружение лексических связываний переменных. См. Замыкания.
Функция, скомпилированная байт-компилятором. См. Тип функции-замыкания.
Заполнитель для реальной функции. Если объект автозагрузки вызывается, Emacs загружает файл, содержащий определение реальной функции, а затем вызывает реальную функцию. См. Автозагрузка.
Вы можете использовать функцию functionp для проверки, является ли объект функцией:
Эта функция возвращает t, если object является функцией любого вида, т. е. может быть передан в funcall. Обратите внимание, что functionp возвращает t для символов, являющихся именами функций, и возвращает nil для символов, являющихся макросами или специальными формами.
Если object не является функцией, эта функция обычно возвращает nil. Однако представление объектов функций сложно, и из соображений эффективности в редких случаях эта функция может возвращать t, даже если object не является функцией.
Также можно узнать, сколько аргументов ожидает произвольная функция:
Эта функция предоставляет информацию о списке аргументов указанной function. Возвращаемое значение — это ячейка cons вида (min . max), где min — минимальное количество аргументов, а max — либо максимальное количество аргументов, либо символ many для функций с аргументами &rest, либо символ unevalled, если function является специальной формой.
Обратите внимание, что эта функция может возвращать неточные результаты в некоторых ситуациях, например:
apply-partially (см. apply-partially).
advice-add (см. Советы для именованных функций).
В отличие от functionp, следующие функции не рассматривают символ как определение функции.
Эта функция возвращает t, если object является встроенной функцией (т. е. примитивом Lisp).
(subrp 'message) ; message — это символ,
⇒ nil ; не объект subr.
(subrp (symbol-function 'message))
⇒ t
Эта функция возвращает t, если object является функцией байт-кода. Например:
(byte-code-function-p (symbol-function 'next-line))
⇒ t
Эта функция возвращает t, если object является объектом функции, который представлен не в виде исходного кода ELisp, а в виде машинного кода или байт-кода. Более конкретно, она возвращает t, если функция встроенная (она же «примитив», см. Что такое функция?), или байт-скомпилирована (см. Байт-компиляция), или скомпилирована в нативный код (см. Компиляция Lisp в нативный код), или загружена из динамического модуля (см. Динамические модули Emacs).
Эта функция возвращает t, если object является интерпретируемой функцией.
Эта функция возвращает t, если object является замыканием, что является частным видом объекта функции. В настоящее время замыкания используются для всех функций байт-кода и всех интерпретируемых функций.
Эта функция работает как func-arity, но только для встроенных функций и без косвенного обращения через символ. Она вызывает ошибку для не встроенных функций. Мы рекомендуем использовать func-arity вместо неё.
Эта функция подобна functionp, за исключением того, что она возвращает nil для списков и символов.
Эта функция возвращает t, если object является встроенным примитивом, написанным на C (см. Тип примитивной функции). Обратите внимание, что специальные формы явно исключены, так как они не являются функциями. Используйте subr-primitive-p, если вам нужно распознавать также специальные формы.