Подтвердить что ты не робот

Зачем использовать # 'перед аргументами функции в emacs- lisp?

Я знаком с Emacs Lisp, но не Common (или любым другим) Lisp. Некоторые программисты Lisp предлагают (например, Базовая функция для emacs), что полезно использовать #' перед аргументами функции в коде Lisp. Например:

(mapc #'my-fun '(1 2 3))

В Emacs Lisp я считаю, что это эквивалентно

(mapc 'my-fun '(1 2 3))

Из справочника elisp, раздел 12.7.

Синтаксис чтения #' является кратким для использования function. следующие формы эквивалентны:

 (lambda (x) (* x x))
 (function (lambda (x) (* x x)))
 #'(lambda (x) (* x x))

и справки для function

Функция

является специальной формой в eval.c.

(function ARG)

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

Итак, это похоже на потенциальную оптимизацию, но не более того. Более того, исходя из фона ML/Haskell, кажется странным рассматривать функцию иначе, чем любые другие данные.

Вопрос:

Согласны ли вы, что #' следует использовать в аргументах emacs-lisp функции? (Краткое объяснение того, почему они необходимы в Common Lisp, также будет замечательным.)

Примечания:

Я думал, что он может читать другую ячейку, когда #' опущен (значение vs function). Но это кажется неправильным, потому что документация для function ничего не говорит о захвате ячейки функции. Это достигается с помощью symbol-function.

Связанные вопросы:

но они, похоже, предполагают, что #' не требуется, по крайней мере, в lambdas.

4b9b3361

Ответ 1

Символ кавычек в #'foo не имеет ничего общего с тем, что находится в 'foo.

#'foo заменяется во время чтения на (function foo). Когда это скомпилировано и выполняется, он ищет функциональное определение, названное foo (defun, flet, labels или подобное).

'foo заменяется во время чтения на (quote foo). Когда это скомпилировано и выполнено, оно просто заменяется символом foo.

Funcall и apply (и, следовательно, обычно функции более высокого порядка) принимают аргументы функции. Обозначение функции может быть функцией или символом, обозначающим функцию, поэтому оба #'foo и 'foo являются указателями функций.

Следовательно, формы 'foo и #'foo кажутся взаимозаменяемыми с первого взгляда. Однако поиск реальной функции выполняется в разное время. #'foo просматривается там, где он вызывается, а функция, названная 'foo, будет отображаться только при ее окончательном применении.

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