Czy istnieje różnica między '#' (lambda… `a` (lambda… `? [Duplicate])

Dec 14 2020

W Practical Common Lisp jest przykład REMOVE-IF-NOTz lambdą:

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

Czy to różni się od:

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

Czy (lambda..)wartość jest zbieżna z formą funkcji cytowanej #'(..)? Na REPL wydaje się, że tak, ale ponieważ jestem nowy w Lisp, mogę coś przeoczyć (i na pewno źle zrozumiałem słownictwo, więc proszę, popraw mnie również w tym).

Odpowiedzi

4 tfb Dec 14 2020 at 19:03

Te dwie rzeczy są, jak podejrzewasz, takie same:

  • #'jest makrem do odczytu i #'xjest odczytywane jako (function x). #'(lambda (...) ...)Czyta się więc jako (function (lambda (...) ...)), gdzie functionjest operatorem specjalnym w CL, który mówi, że jego argument oznacza funkcję;
  • lambdajest zdefiniowane jako makro: rozwinięcie (lambda (...) ...)jest (function (lambda (...) ...): identyczna z poprzednią formą.

Oznacza to #'(lambda (...) ...), (lambda (...) ...)i (function (lambda (...) ...))wszystkie są tym samym w CL: wszystkie oznaczają funkcję określoną przez (lambda (...) ...)w bieżącym środowisku leksykalnym.

Istnieją dwa powody, dla których ludzie mogą nadal używać tej #'(lambda (...) ...)wersji:

  • spójność - potrzebujesz, na przykład, #'fooif foojest funkcją, więc może być postrzegane jako bardziej spójne, aby użyć jej również w lambdaprzypadku;
  • nie zawsze tak było w CL, które lambdamiało taką definicję makra, jak teraz, więc kod, który został napisany między oryginalną specyfikacją CL a standardem ANSI, lub który został napisany przez osoby pamiętające tamte czasy, może używać #'formularza.