Gibt es einen Unterschied zwischen "#" (Lambda ... "und" (Lambda ... ")? [Duplikat]

Dec 14 2020

In Practical Common Lisp gibt es ein Beispiel für REMOVE-IF-NOTein Lambda:

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

Unterscheidet sich das von:

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

Stimmt ein (lambda..)Wert mit der Form der zitierten Funktion überein #'(..)? Auf der REPL scheint es so, aber da ich neu bei Lisp bin, kann ich etwas übersehen (und ich habe sicherlich die falsche Sprache verstanden, also korrigieren Sie mich bitte auch).

Antworten

4 tfb Dec 14 2020 at 19:03

Diese beiden Dinge sind, wie Sie vermuten, gleich:

  • #'ist ein Lesemakro und #'xwird als gelesen (function x). So #'(lambda (...) ...)wird gelesen (function (lambda (...) ...)), wo functionist der spezielle Operator in CL, der sagt, dass sein Argument eine Funktion bezeichnet;
  • lambdawird als Makro definiert: Die Erweiterung von (lambda (...) ...)ist (function (lambda (...) ...): die identische Form wie die vorherige.

Dies bedeutet , dass #'(lambda (...) ...), (lambda (...) ...)und (function (lambda (...) ...))alle die gleiche Sache in CL sind: sie alle bezeichnen die Funktion durch Angabe (lambda (...) ...)in der aktuellen lexikalischen Umgebung.

Es gibt zwei Gründe, warum Benutzer die #'(lambda (...) ...)Version möglicherweise weiterhin verwenden :

  • Konsistenz - Sie benötigen, zum Beispiel , #'foowenn fooeine Funktion ist, so dass er als konsequenter gesehen werden kann es für den zu verwenden , lambdazu Fall;
  • In CL war es nicht immer so, dass lambdaes die Makrodefinition hatte, die es jetzt hat. Daher kann Code, der zwischen der ursprünglichen CL-Spezifikation und dem ANSI-Standard geschrieben wurde oder von Personen geschrieben wurde, die sich an diese Zeiten erinnern, das #'Formular verwenden.