Pull to refresh

Common Lisp: запись лямбда функций

Частый вопрос начинающих лисперов:
в чём отличие записи #'(lambda (x) (expr x)) от (lambda (x) (expr x))? И как правильно писать?

В CL есть специальный оператор function аргументом которого может быть символ или не вычисляемая форма вида (lambda ...).
Результатом вычисления function является функция-объект к которой можно применить apply или funcall.
#' — стандартный макрос Lisp считывателя (reader macro) который раскрывается в (function ...)
Поэтому #'(lambda (x) (expr x)) есть ни что иное, как (function (lambda (x) (expr x))).
Также стандартом определён макрос lambda, который раскрывается в (function (lambda ...)) или кратко #'(lambda ...).

Строго говоря, следующие выражения семантически равнозначны:
(lambda (x) (expr x))
#'(lambda (x) (expr x))
(function (lambda (x) (expr x)))

Вопрос, как наиболее корректно с эстетической (в плане синтаксиса) точки зрения записывать лямбда функции, остаётся открытым и, по всей видимости, не будет закрыт никогда.
С одной стороны, запись вида #'(lambda (x) (expr x)) симметрична записи #'f и код, в этом смысле, выглядит однородно.
С другой стороны, макросы генерирующие лямбда функции наподобие lambda-match из optima никаким образом не могут быть записаны с префиксом #' (function ничего не знает о таких формах, как lambda-match). В этом случае однородно выглядит использование lambda макроса вместе с другими макросами которые раскрываются в лямбда функции.

Один подход:
(let ((xs (list 1 2 3 4 5 6)))
  (mapcar #'(lambda (x)
              (+ x 2))
          (remove-if #'oddp xs)))
;; (4 6 8)

Другой подход:
(let ((xs (list 1 2 3 4 5)))
  (mapcar (lambda (x)
            (+ x 2))
          (remove-if (lambda-match
                       (1 nil)
                       (2 nil)
                       (x   x))
                     xs)))
;; (3 4)


Я предпочитаю использовать lambda макрос.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.