Есть ли разница между `# '(лямбда ...` и `(лямбда ...`? [Дубликат]

Dec 14 2020

В Практическом Common Lisp есть пример REMOVE-IF-NOTс лямбдой:

CL-USER> (remove-if-not #'(lambda (x) (evenp x)) '(1 2 3 4 5))
(2 4)

Это чем-то отличается от:

CL-USER> (remove-if-not (lambda (x) (evenp x)) '(1 2 3 4 5))
(2 4)

(lambda..)Совпадает ли значение с формой цитируемой функции #'(..)? В REPL это кажется так, но, поскольку я новичок в Lisp, я могу кое-что пропустить (и я, конечно же, ошибся в словоблудии, поэтому, пожалуйста, поправьте меня и в этом).

Ответы

4 tfb Dec 14 2020 at 19:03

Эти две вещи, как вы подозреваете, одинаковы:

  • #'является макросом для чтения и #'xчитается как (function x). So #'(lambda (...) ...)читается как (function (lambda (...) ...)), где function- специальный оператор в CL, который говорит, что его аргумент обозначает функцию;
  • lambdaопределяется как макрос: расширение (lambda (...) ...)is (function (lambda (...) ...): форма идентична предыдущей.

Это означает , что #'(lambda (...) ...), (lambda (...) ...)и (function (lambda (...) ...))все одно и то же в CL: все они обозначают функции определяются (lambda (...) ...)в текущей лексической среде.

Есть две причины, по которым люди все еще могут использовать эту #'(lambda (...) ...)версию:

  • согласованность - вам нужна, например #'foo, fooфункция if , поэтому ее можно рассматривать как более последовательную, если она используется и для lambdaслучая;
  • это не всегда было так в CL, который lambdaимел определение макроса, которое есть сейчас, поэтому код, который был написан между исходной спецификацией CL и стандартом ANSI, или который был написан людьми, которые помнят те времена, может использовать эту #'форму.