В чем разница между функцией и командой?

35

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

Q: В Emacs Lisp, в чем разница между функцией и командой?

itsjeyd
источник
13
Конечно, вы имеете на это полное право, и я уверен, что некоторым людям это поможет. Но, FWIW, я не одобряю вопросы и ответы здесь за каждую мелочь, о которой может быть лучше научить кого-то спрашивать саму Emacs . Это один из них, IMO - это не сложно выяснить, и Emacs дает хороший ответ. C-h i, выберите руководство Elisp , i command- помещает вас прямо в узел What is a function?, который делает все это кристально чистым. Помогите пользователям научиться спрашивать Emacs. (Только одно мнение.)
Дрю
1
Тем не менее, вы поставили и ответили на вопрос хорошо.
Дрю
5
@ Дрю Я согласен на 100% учить людей сначала спрашивать Emacs. Основная цель этих конкретных вопросов и ответов состоит в том, чтобы облегчить продвижение правильного использования терминов и, при необходимости, чтобы пользователи знали о различиях между командами и функциями: иногда люди не знают, что это вопрос, который они должны задавать , и иметь общий ресурс для указания на них легче, чем повторять одно и то же содержание снова и снова в комментариях.
itjeyd
1
Тем не менее, спасибо за упоминание о том, как найти соответствующую информацию внутри Emacs :)
itsjeyd
1
Мы согласны - речь идет о помощи пользователям в использовании Emacs. Этот сайт является средством для достижения этой цели.
Дрю

Ответы:

44

Каждая команда является функцией, но не каждая функция также является командой. 1

Команда включает в себя вызов interactive; Вот почему команды обычно называют «интерактивными функциями». Команды могут быть вызваны через M-x name-of-command RET, и они также могут быть связаны с последовательностью клавиш. Обычные функции не включают вызов interactive, не могут быть вызваны с помощью M-x, и вы не можете связать их с последовательностью клавиш. Чтобы запустить функцию, которая не является интерактивной, вы можете нажать M-:( eval-expression), ввести имя функции, а затем значения для всех необходимых аргументов, заключенные в скобки, и нажать RET:

M-: (name-of-function arg1 arg2 arg3) RET

Если функция не должна работать с текущим буфером, вы также можете ввести

(name-of-function arg1 arg2 arg3)

в *scratch*буфере и нажмите C-x C-e( eval-last-sexp) с точкой, расположенной после закрывающей скобки.

Чтобы сделать функцию barдоступной как команду, вы можете обернуть ее в пользовательскую интерактивную функцию ( foo) следующим образом:

(defun foo ()
  (interactive)
  (bar))

Конечно, если barпринимает один или несколько аргументов, вам нужно будет предоставить их для fooправильной работы.

Если вы видите, что люди используют термины «функция» и «команда» взаимозаменяемо, это может указывать (в зависимости от контекста), что они не знают о различиях между основными понятиями.


1 Обратите внимание, что я говорю о defunс здесь. Как отмечает @Stefan в комментариях, клавиатурные макросы являются особым случаем: их можно рассматривать как команды , но они не являются функциями.

itsjeyd
источник
5
Незначительные мелочи: interactive«вызовы» обычно называются объявлениями (сама функция на самом деле ничего не делает).
шости
5
@itsjeyd: На самом деле нет, есть также команды, которые не являются функциями. Это касается макросов клавиатуры . Например M-: (commandp [?a]) RET, (correclty) скажет вам, что [?a]это команда, но это не функция.
Стефан,
@Stefan Спасибо за указание на это. Я обновил свой ответ.
itsjeyd