Warum hat elisp keine Namespaces?

40

F: Warum hat elisp keine Namespaces und wie können wir sie bekommen?

Elisp hat keine anderen Namespaces als den globalen, was zu der Kodierungskonvention geführt hat, dass allen globalen Funktionen, Variablen und Konstanten ein eindeutiges Präfix vorangestellt wird.

Abgesehen von dem Ärgerfaktor scheint es mir auch ein Problem zu sein, das angesichts 1) der ständig wachsenden Anzahl großartiger Bibliotheken und Pakete und 2) der fortbestehenden Existenz von Legacy-Funktionen und -Variablen, die entweder die Präfixkonvention nicht respektieren, oder sind so eigenwillig, dass es keine wirklich gute Präfixoption gibt, die sie verwenden könnten. Dies bedeutet auch, dass regelmäßige Versuche, älteren Code (wie beim Übergang von clnach cl-lib) zu rationalisieren, nicht trivial sind. (Obwohl ich für das Aufräumen froh bin, vergieße ich trotzdem jedes Mal eine Träne, wenn ich so etwas schreibe cl-find).

Ich stöberte herum, um herauszufinden, warum elisp nach einigen Jahrzehnten der Nutzung immer noch keine Namespaces hat, war aber ein wenig überrascht über die bescheidene Ernte. Die Wiki-Seite zu Namespaces ist recht kurz. Nic Ferrier hat eine etwas längere Behandlung des Problems und es gibt auch einen relativ neuen Thread über Emacs-Entwicklung . Es gibt einen alten Stapelüberlauf-Thread aus dem Jahr 2010, in dem die Möglichkeit der Verwendung von Makros zum Implementieren von Namespaces erörtert wird. Ein weiteres Beispiel für den Makroansatz finden Sie hier . Es gibt mindestens ein paar Implementierungen ( hier und hier , mit einer Beschreibung der letzteren hier) da draußen, aber sie haben seit ein paar Jahren nicht mehr viel Aktivität gesehen, und ich bin nicht auf Bibliotheken gestoßen, die sie verwenden.

Ich nehme an, wenn das Hinzufügen von Namespaces einfach wäre, wäre dies bereits erledigt. Damit:

  • Was sind die technischen Hindernisse für das Hinzufügen von Namespaces zu elisp?
  • Würde das Hinzufügen von Namespaces einen Großteil des vorhandenen Codes beschädigen?
  • Muss diese Funktionalität organisch sein (Änderungen am Interpreter selbst), oder kann sie wirklich über Makros aufgebaut werden?
Dan
quelle
6
Sie können sich dies ansehen: github.com/Bruce-Connor/names Es scheint eine abwärtskompatible (mit der aktuellen manuellen Methode zum Trennen von Namen) Implementierung von automatischen Namespaces zu sein. (Und ich bin mir zu 99% sicher, dass ich eine andere solche Bibliothek gesehen habe, die es dem Entwickler ermöglicht, eine Teilmenge von Funktionen mit Namespaces zu exportieren, die kürzlich in einigen Emacs-Blogs erwähnt wurden, aber ich konnte sie nicht zurückfinden.)
T. Verron
2
Als zweites solltest du dir den obigen Link ansehen. Es ist ein sehr neues (im letzten Monat veröffentlichtes) und sehr robustes Namespace-Makro. Ich arbeite immer noch ein paar Probleme in Bezug auf die Kompatibilität mit Tools wie edebug aus, aber das Paket funktioniert. Die Beantwortung Ihrer Frage ist ein sehr langer Aufsatz (es gab viele technische Hindernisse), aber ich werde versuchen, ihn in den nächsten Wochen in Blog-Posts zu veröffentlichen.
Malabarba
1
Ich denke, Namespaces bedeuten verschiedene Dinge. Ich hätte gesagt, dass emacs mehrere Namespaces hat: einen für Variablen, einen für Funktionen und Makros, einen für Gesichter und für Themen und…
Harald Hanche-Olsen
1
@ HaraldHanche-Olsen kann man das sicher sagen. In diesem Zusammenhang fragt er, warum es keine paketbezogenen Namespaces gibt.
Malabarba

Antworten:

28

Warum keine Namespaces?

Weil es kompliziert ist und niemand es für dringend genug gehalten hat, den vollen Sprung noch zu wagen. Dies wurde bereits in der Dev-Liste diskutiert (mehrmals), und es wurde versprochen, dies nach dem Wechsel zu Git zu beheben.

In der Zwischenzeit habe ich eine eigene Lösung geschrieben (siehe unten für eine Liste von Optionen).

Was sind die technischen Hindernisse?

Im Freien gibt es drei große Hindernisse, die Sie überwinden müssen, damit Namespaces sogar die Möglichkeit haben, an einem aktuellen Emacs zu arbeiten:

  • Sie müssen ändern, wie Symbole interniert werden (dies ist der einfache Teil).
  • Der Byte-Compiler muss Namespaces verstehen.
  • Die von verwendete Autoload-Generation package.elmuss Namespaces verstehen.

Es ist nicht trivial, diese drei Dinge zu patchen, um damit zu arbeiten, wie auch immer Sie kommen, um Namespaces zu implementieren. Wenn Sie sich nur der neuesten Emacs-Version widmen, können Sie dies auf jeden Fall tun. Wenn Sie eine Art Paket schreiben möchten, das auch frühere Versionen unterstützt (wie die gesamte 24er-Familie), wird dies zu einer echten Herausforderung.

Darüber hinaus gibt es Tonnen von anderen optionalen Hindernissen. Elisp ist großartig, weil die verfügbaren Tools so leistungsfähig sind, dass ALLE diese gepatcht werden müssten, um mit Namespaces zu arbeiten. Zu den wichtigsten gehören:

  • Edebug
  • eval-defun
  • eval-last-sexp
  • Schleim

Würde es viel vorhandenen Code brechen?

Nicht, wenn du es richtig machst.

Ist das etwas, das organisch sein muss, oder könnte es wirklich über Makros aufgebaut werden?

Idealerweise wäre es organisch, das wird normalerweise diskutiert, wenn es in der Entwicklerliste auftaucht. Aber es kann gut genug gemacht werden, während es oben gebaut wird.
Hier einige Beispiele aus dieser Liste :

Malabarba
quelle
1
Danke - das war eine sehr informative Sicht auf das Thema. Ich bin gespannt auf Ihren letzten Punkt: Ihre namesLösung. Ich frage mich, ob es irgendeinen Grund gibt, zu vermuten, dass eine organische, integrierte Lösung in nicht allzu ferner Zukunft verfügbar sein wird, oder ob wir einfach die von Ihnen bereitgestellte integrierte Lösung übernehmen sollten .
Dan
1
@ Dan Ja, das gibt es. . Das heißt, es gibt keinen Grund , nicht zu verabschieden Namen in der Zwischenzeit. Es ist voll kompatibel mit Emacs' Konventionen, so dass jedes Paket mit Namen frei verwenden zu stoppen Namen jederzeit, und der Benutzer nichts wissen.
Malabarba
Sie sollten namelessdiese Liste wirklich ergänzen :) Es ist eine brillante Idee und löst das Problem sehr ordentlich.
Clément
22

Als dies das letzte Mal auf emacs-devel diskutiert wurde, hörte die Diskussion auf, als Leute wie Lars darauf hinwiesen, dass sie gerne in der Lage sind, M-x grepetwas zu tun . Das Hinzufügen von Namespaces zu Elisp sollte nicht allzu schwierig sein, aber es ist ein weiteres Problem, alle vertrauten Tools zu verwenden, um sie richtig zu handhaben.

Stefan
quelle
Ich denke, das könnte leicht 'behoben' werden, indem Aliase für die am häufigsten verwendeten Funktionen (oder vielleicht für alle) erstellt werden
Jesse,
1
Die Notwendigkeit zu "grep" tritt normalerweise während der Entwicklung eines Pakets auf, wenn Sie wissen müssen, wo eine Variable / Funktion in anderen Paketen verwendet werden kann, damit sie auf beliebige Variablen / Funktionen angewendet werden kann und nicht nur auf bestimmte wichtige. Aus diesem Grund macht das Hinzufügen einiger Aliase keinen Unterschied. Ein weiterer Grund, warum mit nicht hilft, ist, dass das Hinzufügen eines Alias ​​nicht hilft, die Verwendungen zu finden, die diesen Alias ​​nicht verwenden.
Stefan