Ich habe meine Hände nass mit Emacs Lispeln, und eine Sache, die mich manchmal stolpert, ist der dynamische Bereich. Gibt es dafür viel Zukunft? Die meisten Sprachen, die ich kenne, verwenden das statische Scoping (oder sind in das statische Scoping übergegangen, wie Python), und wahrscheinlich, weil ich es besser kenne, bevorzuge ich es. Gibt es bestimmte Anwendungen / Instanzen oder Beispiele, in denen der dynamische Bereich sinnvoller ist?
Es gibt eine gute Diskussion dieses Problems hier . Der nützlichste Teil, der zu Ihrer Frage gehört, ist:
%Vor%Dynamische Bindungen sind großartig für Ändern des Verhaltens von Subsystemen. Angenommen, Sie verwenden eine Funktion 'foo' Dies erzeugt die Ausgabe mit 'print'. Aber manchmal möchtest du es auch erfassen Sie die Ausgabe in einem Puffer Ihres Wählen. Mit dynamischer Bindung ist es das einfach:
(Und wenn du so etwas benutzt hast a viel, Sie würden es in einem Makro kapseln - Aber zum Glück ist es schon erledigt 'With-output-to-temp-buffer'.)
Das funktioniert, weil 'foo' das verwendet dynamische Bindung des Namens 'Standard-Ausgabe', so können Sie ersetze dafür deine eigene Bindung Name, um das Verhalten von 'foo' zu ändern - und von allen Funktionen, die 'foo' Anrufe.
In einer Sprache ohne dynamische Bindung, Du würdest wahrscheinlich ein optionales hinzufügen Argument zu 'foo', um einen Puffer anzugeben und dann würde "foo" das an alle weitergeben ruft auf "drucken". Aber wenn 'foo' anruft andere Funktionen, die selbst anrufen 'Print' müssen Sie diese ändern funktioniert auch. Und wenn 'drucken' hatte eine andere Option, sagen wir "Druck-Ebene", Sie müssten das optional hinzufügen Argument auch ... Alternativ, Sie könnte mich an den alten Wert von erinnern 'Standard-Ausgabe', ersetzen Sie Ihre neue Wert, rufen Sie 'foo' und stellen Sie dann die alter Wert. Und denken Sie daran, damit umzugehen nicht-lokale Exits mit 'throw'. Wann Du bist damit fertig, du wirst sehen dass du dynamisch implementiert hast verbindlich!
Das heißt, lexikalische Bindung ist IMHO viel besser für 99% der Fälle. Beachten Sie, dass moderne Lisps nicht dynamisch gebunden sind - nur wie Emacs Lisp.
Darüber hinaus unterstützen moderne Sprachen wie Python und Ruby, die von Lisp etwas inspiriert wurden, in der Regel lexikalische Bindungen auf unkomplizierte Weise, wobei dynamische Bindungen ebenfalls verfügbar, aber weniger einfach sind.
Wenn Sie das Emacs-Papier (1981) lesen, gibt es einen speziellen Abschnitt < a href="http://www.gnu.org/software/emacs/emacs-paper.html#SEC15"> "Sprachfunktionen für Erweiterbarkeit" , die diese Frage adressieren. In Emacs gibt es auch den zusätzlichen Bereich puffer-lokaler (Datei lokaler) Variablen.
Ich habe den relevantesten Teil unten zitiert:
Formalparameter können nicht ersetzt werden Dynamischer Bereich
Einige Sprachdesigner glauben das dynamische Bindung sollte vermieden werden, und explizites Argument sollte übergeben werden stattdessen verwendet. Stellen Sie sich die Funktion A vor bindet die Variable FOO und ruft die Funktion B, die die Funktion aufruft C und C verwenden den Wert von FOO. Angeblich sollte A den Wert als übergeben ein Argument für B, das es passieren sollte als ein Argument zu C.
Dies kann nicht in einem erweiterbaren ausgeführt werden System jedoch, weil der Autor von Das System kann nicht wissen, was alles Parameter werden sein. Stellen Sie sich vor, dass die Funktionen A und C sind Teil eines Benutzers Erweiterung, während B Teil des ist Standardsystem. Die Variable FOO tut es nicht im Standard vorhanden; es ist Teil der Erweiterung. Benutzen explizite Argumentübergabe würde muss B ein neues Argument hinzufügen, was bedeutet, B und alles neu zu schreiben das ruft B. Im häufigsten Fall, B ist der Editor-Befehlsverteiler Schleife, die von einem schrecklichen aufgerufen wird Anzahl der Plätze.
Was noch schlimmer ist, C muss auch bestanden werden zusätzliches Argument. B bezieht sich nicht zu C nach Namen (C gab es nicht, wenn B wurde geschrieben). Es findet wahrscheinlich ein Zeiger auf C in der Befehlsausgabe Tabelle. Dies bedeutet, dass der gleiche Anruf was manchmal C anspricht Rufen Sie jeden Editor-Befehl an Definition. Also die ganze Bearbeitung Befehle müssen neu geschrieben werden, um sie zu akzeptieren und ignoriere das zusätzliche Argument. Durch jetzt ist nichts vom ursprünglichen System verlassen!