wird für den dynamischen Bereich verwendet?

8

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?

    
hatmatrix 05.06.2010, 06:32
quelle

2 Antworten

14

Es gibt eine gute Diskussion dieses Problems hier . Der nützlichste Teil, der zu Ihrer Frage gehört, ist:

  

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:

%Vor%
  

(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.

  • Common Lisp unterstützt beide Formen der Bindung, obwohl der lexikalische viel mehr verwendet wird
  • Die Schema-Spezifikation spezifiziert nicht einmal die dynamische Bindung (nur lexikalisch), obwohl viele Implementierungen beides unterstützen.

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.

    
Eli Bendersky 05.06.2010, 06:44
quelle
7

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!

    
Trey Jackson 06.06.2010 03:06
quelle

Tags und Links