Frage

Schema verwendet einen einzigen Namespace für alle Variablen, unabhängig davon, ob sie auf Funktionen oder andere Arten von Werten gebunden sind. Common Lisp trennt die beiden, so dass die Kennung „Hallo“ auf eine Funktion in einem Kontext beziehen, und eine Zeichenfolge in einem anderen.

(Anm. 1: Diese Frage muss ein Beispiel für die oben, fühlen sich frei, es zu bearbeiten und fügen Sie ein, oder E-Mail der ursprüngliche Autor mit ihm und ich werde tun, so)

Doch in manchen Kontexten, wie Funktionen als Parameter für andere Funktionen geben, muss der Programmierer explizit unterscheiden, dass er eine Funktion Variable spezifiziert, sondern als eine nicht-Funktion Variable, durch #' verwenden, wie in:

(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)

Ich habe immer als dies ein bisschen eine Warze sein, aber ich habe vor kurzem über eine Argument , dass dies tatsächlich ein Merkmal ist:

...das wichtiger Unterschied liegt eigentlich in der Syntax von Formen, nicht in dem Art von Objekten. Ohne zu wissen, etwas über die Laufzeitwerte beteiligt ist, ist es ganz klar, dass das erste Element einer Funktionsform muss eine Funktion sein. CL nimmt diese Tatsache und es macht einen Teil der Sprache, zusammen mit Makro- und Sonderformen, die auch kann (und muß) werden statisch bestimmt. Also meine Frage ist: Warum würden Sie das wollen Namen von Funktionen und die Namen der Variablen in der gleichen sein Namespace, wenn die primäre Verwendung von Funktionsnamen ist zu erscheinen, wo ein Variablenname würde selten angezeigt werden soll?
Betrachten wir den Fall von Klassennamen: Warum sollte eine Klasse namens FOO verhindern die Verwendung von Variablen namens FOO? Das einzige Mal, dass ich das mit Bezug würde Klasse mit dem Namen FOO ist in Kontexten, die einen Klassennamen erwarten. Wenn auf die seltene Gelegenheit, ich brauche das Klassenobjekt zu erhalten, die an die gebunden ist Klassenname FOO, gibt es FIND-CLASS.

Dieses Argument hat einigen Sinn für mich aus Erfahrung; gibt es einen ähnlichen Fall in Haskell mit Feldnamen, mit denen auch Funktionen sind die Felder zuzugreifen. Dies ist ein wenig umständlich:

data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)

Dies wird durch ein paar zusätzliche Syntax gelöst ist, gemacht besonders schön durch die NamedFieldPuns Erweiterung:

isOrigin2 Point{x,y} = (x == 0) && (y == 0)

Also, auf die Frage, über Konsistenz, was sind die Vor- und Nachteile, sowohl für Common Lisp vs. Schema und im Allgemeinen von einem einzigen Namensraum für alle Werte im Vergleich zu separat diejenigen für Funktionen und Nicht-Funktionswerte?

War es hilfreich?

Lösung

Die beiden unterschiedlichen Ansätze haben Namen: Lisp-1 und Lisp-2. Ein Lisp-1 hat einen einzelnen Namensraum für beide Variablen und Funktionen (wie in Schema), während ein Lisp-2 separate Namensräume für Variablen und Funktionen hat (wie in Common Lisp). Ich erwähne das, weil Sie sich nicht von der Terminologie bewusst sein, da Sie nicht in Ihrer Frage darauf bezog sich.

bezieht sich auf diese Debatte :

  

Ob ein separater Namensraum für Funktionen ist ein Vorteil ist eine Quelle des Streites in der Lisp-Community. Es wird in der Regel als Lisp-1 vs. Lisp-2 Debatte bezeichnet. Lisp-1 bezieht sich auf Schema des Modells und Lisp-2 bezieht sich auf Common Lisp des Modells. Diese Namen wurden in einem 1988 Papier von Richard P. Gabriel und Kent Pitman, geprägt, die weitgehend die beiden Ansätze miteinander vergleicht.

Gabriel und Pitman das Papier mit dem Titel Technische Probleme der Trennung in Funktionszellen und Wert Cells Adressen genau diese Frage.

Andere Tipps

Tatsächlich, wie in das Papier von Richard Gabriel und Kent Pitman , die Debatte über ist Lisp-5 gegen Lisp-6, da gibt es mehr anderen Namespaces bereits dort werden in den Papiertypnamen erwähnt, Variablennamen, Blocknamen und Erklärung Namen. edit: das scheint falsch zu sein, wie Rainer im Kommentar betont: Schema scheint tatsächlich eine Lisp-1 zu sein. Im Folgenden ist weitgehend unbeeinflusst von diesem Fehler, though.

Ob ein Symbol etwas bezeichnet ausgeführt oder etwas werden, um im folgenden aus dem Zusammenhang immer klar. Werfen Funktionen und Variablen in den gleichen Namensraum ist in erster Linie eine Einschränkung: der Programmierer nicht den gleichen Namen für eine Sache und eine Aktion verwenden kann. Was für ein Lisp-5 aus diesem bekommt ist nur, dass einige syntaktische Aufwand für die Referenzierung etwas von einem anderen Namespace als das, was der aktuelle Kontext impliziert vermieden wird. bearbeiten. Das ist nicht das ganze Bild, sondern nur die Oberfläche

Ich weiß, dass Lisp-5 Befürworter wie die Tatsache, dass die Funktionen Daten sind, und dass dies in der Sprache Kern ausgedrückt. Ich mag die Tatsache, dass ich eine Liste „Liste“ nennen kann und ein Auto „Auto“ ohne meinen Compiler verwirrend, und Funktionen sind grundsätzlich besondere Art von Daten sowieso. edit: das ist mein Hauptpunkt:. Eigener Namensraum gar nicht eine Warze ist

Ich mochte auch was Pascal Constanza musste sagen darüber.

Ich habe eine ähnliche Unterscheidung in Python (Unified Namespace) vs Rubin (distinct Namespaces für Methoden vs nicht-Methoden) erfüllt. In diesem Zusammenhang ziehe ich Python Ansatz - zum Beispiel mit diesem Ansatz, wenn ich eine Liste der Dinge machen will, von denen einigen Funktionen sind, während andere nicht sind, habe ich nicht etwas anderes mit ihrem Namen zu tun je nach ihrer „Funktion-ness“, zum Beispiel. Ähnliche Überlegungen gelten für alle Fälle, in denen Objekte funktionieren eher zu bandied um als genannt (Argumente und Rückgabewerte aus, Funktionen höherer Ordnung, etc, etc).

Nicht-Funktionen aufgerufen werden können, auch (wenn ihre Klassen __call__ definieren, im Fall von Python - ein Sonderfall „Überladen von Operatoren“), so dass die „kontextuelle Unterscheidung“ ist nicht unbedingt klar, entweder

Aber meine „Lisp-oid“ Erfahrung ist / war meist mit Schema statt Common Lisp, so dass ich kann unbewusst durch die Vertrautheit mit dem einheitlichen Namensraum, der am Ende aus dieser Erfahrung kommt vorgespannt werden.

Der Name einer Funktion in Schema ist nur eine Variable mit der Funktion als Wert. Ob ich (define x (y) (z y)) oder (let ((x (lambda (y) (z y)))) tun, ich definiere eine Funktion, die ich anrufen kann. So ist die Idee, dass „ein Variablenname würde selten angezeigt werden soll, um dort“ ist eine Art specious soweit Schema betrifft.

Schema ist eine charakteristische funktionale Sprache, so Funktionen wie Daten zu behandeln, ist eine seiner Lehren. Funktionen werden eine Art von ihrem eigenen zu haben, das wie alle anderen Daten gespeichert ist, ist ein Weg, auf dem Gedanken tragen.

Der größte Nachteil ich, zumindest für Common Lisp zu sehen, ist die Verständlichkeit. Wir können alle einig, dass es verschiedene Namensräume für Variablen und Funktionen verwendet, aber wie viele gibt es? In PAIP, Norvig zeigte, dass es "mindestens sieben" Namespaces hat.

Wenn eines der klassischen Bücher der Sprache, die von einem hoch angesehenen Programmierer geschrieben, kann in einem veröffentlichten Buch nicht einmal sagen, für bestimmte, ich denke, es gibt ein Problem. Ich habe kein Problem mit mehreren Namensräumen haben, aber ich wünschte, die Sprache war, zumindest, einfach genug, dass jemand könnte diesen Aspekt davon verstehen vollständig.

Ich fühle mich wohl das gleiche Symbol für eine Variable und eine Funktion, aber in dem Unbekannten Bereich, die ich aus Angst, mit verschiedenen Namen zurückgreifen (kollidiert Namespaces kann wirklich schwer zu debuggen sein!), Und das sollte wirklich nie der Fall sein.

Es gibt gute Dinge für beide Ansätze. Ich jedoch feststellen, dass, wenn es darauf ankommt, ziehe ich es, die sowohl eine Funktion LIST und eine Variablenliste als einer von ihnen falsch buchstabieren zu müssen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top