Почему я должен использовать # вместе с лямбдой? Обычно это написано так, поэтому я думаю, что это хорошая форма. Но эти строки кажутся мне равными:
Ответ 2
В разных диалектах Lisp он отличается. Следующие использует Common Lisp:
Первая # '- короткая нотация для (function...). Итак, следующие только текстовые различия, но Common Lisp читает их как одно и то же:
#'(lambda (x) (* x 2))
и
(function (lambda (x) (* x 2)))
# 'является readmacro и преобразуется, когда код Lisp считывается системой Lisp.
Если Lisp оценивает
(function (lambda (x) (* x 2)))
система Lisp создает объект функции, а FUNCTION возвращает ее как значение.
Итак, всякий раз, когда вам нужна функция как значение, вам нужно написать ее так. Функция как значение требуется, когда вы хотите передать ее другим функциям в качестве аргумента, когда вы хотите вернуть ее из функции или когда вы хотите сохранить ее в переменной. Примеры:
(map #'(lambda (x) (* x 2)) '(1 2 3))
(defun (y) #'(lambda (x) (* x y)))
(defparameter *twice-fn* #'(lambda (x) (* x 2)))
Теперь, что такое (lambda (x) (* x 2))?
В зависимости от контекста это две разные вещи.
Лямбда-выражение
Вместо имени функции можно использовать выражение лямбда:
(function foo) and (function (lambda (x) (* x 2)))
и
(foo 17) and ((lambda (x) (* x 2)) 17)
Выше два являются законными синтаксисом Common Lisp. Там может быть использовано выражение лямбда.
Обратите внимание, что следующие две формы нелегальные в Common Lisp:
(#'(lambda (x) (* x 2)) 17) ; illegal in Common Lisp
(function #'(lambda (x) (* x 2))) ; illegal in Common Lisp
Макрос
Во время стандартного процесса стандартизации Lisp добавлен макрос LAMBDA (он не был частью первого описания CLtL1, Common Lisp). Это позволяет писать немного более короткий код. Пример:
(lambda (x) (* x 2))
В приведенном выше примере LAMBDA является макросом. Во время расширения макроса он будет расширен до:
(function (lambda (x) (* x 2)))
Помните, что в форме FUNCTION внутренняя лямбда является частью лямбда-выражения, обозначает функцию и не будет расширяться.
Итак, теперь три примера сверху можно записать в виде:
(map (lambda (x) (* x 2)) '(1 2 3))
(defun (y) (lambda (x) (* x y)))
(defparameter *twice-fn* (lambda (x) (* x 2)))
Он немного короче, выглядит немного менее загроможденным и выглядит немного более похожим на код схемы. Это просто выглядит немного лучше для программистов, используемых для чтения и записи кода схемы.
Резюме
a) (функция (lambda (x) (* x 2))) является "истинным" способом записи кода, который возвращает функцию как значение.
b) # '(lambda (x) (* x 2)) является более коротким обозначением выше
c) (lambda (x) (* x 2)) еще короче, но использует макрорасширение для создания формы a).