2016-07-21 50 views
4

Emacs Lisp ist ein Dialekt von LISP und vor allem Scheme. Die meisten Schema-Interpreter haben eine Optimierung der Tail Recursion, aber Emacs Lisp nicht. Ich habe den Grund in "info elisp" eine Weile durchsucht, aber ich finde es nicht.Warum gibt es keine Optimierung der Schwanzrekursion in Emacs Lisp, aber nicht wie andere Schema?

P.S. Ja, es gibt eine andere Iterationssyntax wie "while" in elisp, aber ich kann immer noch keinen guten Grund finden, warum sie Tail-Rekursion nicht wie andere Schema-Interpreter implementiert haben.

+3

Was gab Ihnen den Eindruck, dass elisp vor allem mit Schema verwandt war? Wie Lisps gehen, sind die beiden sehr unterschiedlich. – phils

+4

Es ist überhaupt kein Dialekt von Schema. Es ist ein Dialekt von Lisp, und die meisten Lisp-Dialekte machen keine Tail-Rekursion. – Barmar

+3

Es ist wahrscheinlich am engsten mit Maclisp verwandt, das aus den 1970er Jahren stammt. Es hatte keine Schwanzrekursion. – Barmar

Antwort

9

Emacs Lisp wurde in den 1980er Jahren erstellt. Der Lisp-Dialekt, den der Emacs-Autor (Richard Stallman) damals am meisten kannte, war MIT Maclisp, und Emacs Lisp ist dem sehr ähnlich. Es verwendete dynamisches Variablen-Scoping und hatte keine lexikalischen Schließungen oder Optimierung der Tail-Rekursion, und Emacs Lisp ist das gleiche.

Emacs Lisp unterscheidet sich sehr von Schema. Der größte Unterschied besteht darin, dass Scheme lexikalisch begrenzt ist, aber dies wurde erst kürzlich zu Emacs Lisp hinzugefügt und muss pro Datei aktiviert werden (indem ;;; -*- lexical-binding: t -*- in die erste Zeile gesetzt wird), da dies standardmäßig viele Inkompatibilitäten verursachen würde .

Es gab einige Arbeit, um Emacs Lisp mit Guile, einem Scheme-Dialekt zu ersetzen. Aber es ist nicht klar, ob es jemals Früchte tragen wird.

+4

Ich denke, Sie beziehen sich wahrscheinlich in diesem letzten Absatz auf das Guile-Emacs-Projekt, in dem der elisp-Interpreter durch List ersetzt wird. Es geht nicht darum, elisp durch Schema zu ersetzen - der Punkt ist, dass Guile gemacht wurde, um elisp direkt zu unterstützen. Wenn Sie daran gedacht haben, dann ist in der Tat viel harte Arbeit in das Projekt geflossen - ob es jemals zu dem Punkt kommen wird, an dem es wirklich Teil des Standard-GNU-Emacs werden könnte und würde. – phils

+0

@phils Danke, ich habe diesen letzten Absatz überarbeitet. – Barmar

5

Emacs Lisp hatte dynamische Scoping als seine wichtigste/einzige Scoping-Regel für die ersten 25 Jahre seines Lebens. Das dynamische Scoping ist grundsätzlich nicht mit der Optimierung der Tail-Rekursion kompatibel, so dass bis zu Emacs-24 (welches das lexikalische Scoping einführte) diese Optimierung kaum oder überhaupt nicht interessiert war.

Heutzutage könnte ELisp manchmal von der Optimierung der Tail-Rekursion profitieren, und es wurden einige Patches dazu geschickt, aber das wurde noch nicht integriert. Das Fehlen von Tail-Recursion-Optimierung sowie die relativ ineffiziente Implementierung von Funktionsaufrufen hat den ELisp-Stil beeinflusst, so dass Rekursion nicht sehr oft verwendet wird, was wiederum die Vorteile der Hinzufügung der Optimierung von Tail-Aufrufen reduziert.

3

Sieht aus wie jemand eine Implementierung von TCO in Emacs Lisp gemacht hat: https://github.com/Wilfred/tco.el. Ich habe selbst nicht mit ihr gespielt, aber vielleicht möchten Sie es ausprobieren, wenn Sie TCO in Emacs Lisp sehen wollen.