Warum sagt Clojure 1.3, dass Variablen nicht als dynamisch deklariert werden, wenn ich sie als dynamisch deklariert habe? [geschlossen]

7

Ich portiere Clojure Code (in einem Leiningen Projekt) von 1.2 auf 1.3 und habe Probleme. Zusätzlich zu dem Code selbst funktioniert nicht mehr, ich bekomme Dutzende von Warnmeldungen wie diese:

%Vor%

Dies passiert, obwohl ich bereits die korrekten Änderungen an vars vorgenommen habe, die ich zur Aufrechterhaltung des Status verwende. Für den obigen Fehler enthält der Code beispielsweise Folgendes:

%Vor%

Ich bekomme diese Fehler an zwei Stellen: erstens, von der Befehlszeile, als Ergebnis der Ausführung von lein swank ; und zweitens von Emacs REPL, nachdem ich meine core.clj Datei mit C-c C-w kompiliert habe.

Um absolut vollständig zu sein, hier ist meine project.clj -Datei:

%Vor%

Abgesehen davon, dass mein Code funktioniert, würde ich gerne verstehen, warum ich diese Fehler bekomme und warum ich sie an beiden Orten bekomme. Danke für deine Hilfe.

    
Gregg Williams 21.11.2011, 23:30
quelle

2 Antworten

15

Es ist ein einfacher Tippfehler.

%Vor%

sollte sein:

%Vor%

passiert uns allen!

    
Scott 21.11.2011, 23:34
quelle
11

Sie sollten in Erwägung ziehen, refs oder atoms anstelle von vars zu verwenden, um den Zustand beizubehalten.

Um die Clojure-Dokumentation zu zitieren:

  

Vars bieten einen Mechanismus, um auf einen veränderbaren Speicherort zu verweisen, der auf einer -Pre-Thread -Basis dynamisch neu an einen neuen Speicherort gebunden werden kann.

(Betonung meiner.)

Vars kann mit dem Makro binding auf einen neuen Wert (für den aktuellen Thread) gesetzt werden. Bis zu Clojure 1.2 kann jede Var wie diese rebound sein, aber da Clojure 1.3 vars explizit als ^:dynamic deklariert werden muss, um dies zu ermöglichen. (Soweit ich weiß, ist der Grund eine drastische Beschleunigung der var-Look-Ups für den häufigen Fall, dass keine Neubindung erfolgt.)

Es ist eine allgemeine Konvention (aber nicht mehr), vars zu geben, die Rebound-Namen wie folgt sein sollen: *foobar* . Aufgrund dieser Konvention gibt der Compiler eine Warnung aus, wenn eine Variable wie diese angezeigt wird, die nicht als dynamisch deklariert ist.

Zusammenfassend:

  • Wenn Sie nur einen Wert deklarieren möchten, der sich während der Laufzeit nicht ändert, verwenden Sie eine Variable und löschen Sie die * um den Namen.
  • Wenn Sie den Wert pro Thread ändern möchten, deklarieren Sie var dynamic.
  • Wenn Sie den globalen Status (nicht pro Thread) beibehalten möchten, verwenden Sie einen der anderen referenziellen Typen: atom , ref (falls Sie Transaktionen benötigen) oder agent ( für asynchrone Änderung).
Christian Berg 22.11.2011 09:11
quelle