Зачем использовать #' с лямбдой?
Вопрос
Почему я должен использовать #' вместе с лямбдой?Обычно так пишут, так что, думаю, это хороший тон.Но мне эти строки кажутся равными:
> (mapcar #'(lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
> (mapcar (lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
Кто-нибудь хочет просветить новичка о разнице?
Решение
#'
это сокращение от function
, который возвращает указатель на функцию (вместо ее применения). lambda
возвращает функцию, и обычно требуется указатель на эту функцию.Поскольку это настолько распространено, существует также макрос (в пространстве переменных), который делает это за вас, и который называется lambda
также.Обе строки кода идентичны.
Что лучше, сводится к Дебаты о Lisp-1/Lisp-2:в Common Lisp вы можете сделать и то, и другое благодаря макросу.Как всегда, будьте последовательны.
Другие советы
В разных диалектах Лиспа все по-разному.Ниже используется Common Lisp:
Первый #' — это краткое обозначение (функция...).Таким образом, следующие тексты отличаются только текстуально, но Common Lisp читает их как одно и то же:
#'(lambda (x) (* x 2))
и
(function (lambda (x) (* x 2)))
#' — это макрос чтения, который преобразуется, когда код 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)))
Итак, что такое (лямбда (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
Макрос
В процессе стандартизации Common Lisp был добавлен макрос LAMBDA (он не был частью первого описания Common Lisp, CLtL1).Это позволяет писать немного более короткий код.Пример:
(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)))
Он немного короче, выглядит менее загроможденным и немного больше похож на код Scheme.Просто это выглядит немного лучше для программистов, привыкших читать и писать код Scheme.
Краткое содержание
а) (function (lambda (x) (* x 2))) — это «верный» способ написать код, который возвращает функцию в качестве значения.
б) #'(лямбда (x) (* x 2)) — это более короткая запись, приведенная выше.
в) (лямбда (х) (* х 2)) еще короче, но использует расширение макросов для создания формы а).