Müssen Sie die Realisierung fauler Folgen vor / nach elementweisen Imperativoperationen erzwingen?

Wenn ich eine nebenwirkende / mutierende Operation an einzelnen Datenstrukturen durchführe, die für jedes Mitglied der Lazy Sequence using spezifisch sindmapMuss ich (a) anrufen?doall Erstens, um die Realisierung der ursprünglichen Sequenz zu erzwingen, bevor die imperativen Operationen ausgeführt werden, oder (b) Aufrufdoall die Nebenwirkungen zu erzwingen, bevor ich eine Funktionsoperation über die resultierende Sequenz abbilden?

Ich glaube das neindoalls sind notwendig, wenn keine Abhängigkeiten bestehenzwischen Elemente beliebiger Reihenfolge, damap Eine Funktion kann erst auf ein Mitglied einer Sequenz angewendet werden, wenn die Funktionen vonmaps, die diese Sequenz erzeugt haben, wurden auf das entsprechende Element der früheren Sequenz angewendet. Somit,für jedes Elementwerden die Funktionen in der richtigen Reihenfolge angewendet, obwohl eine der Funktionen Nebenwirkungen hervorruft, von denen eine spätere Funktion abhängt. (Ich weiß, dass ich dieses Element nicht annehmen kanna wurde vor dem Element geändertb ist, aber das spielt keine Rolle.)

Ist das richtig?

Das ist die Frage, und wenn sie klar genug ist, müssen Sie nicht weiter lesen. Der Rest beschreibt detaillierter, was ich versuche.

Meine Anwendung hat eine Folge von Defrecord-Strukturen ("Agenten"), von denen jede einige core.matrix-Vektoren enthält (vec1, vec2) und eine core.matrix Matrix (mat). Angenommen, ich beschließe aus Gründen der Geschwindigkeit, die Matrix (destruktiv, nicht funktional) zu modifizieren.

Das Programm führt die folgenden drei Schritte für jeden Agenten durch, indem es aufruftmap, dreimal, um jeden Schritt auf jeden Agenten anzuwenden.

Aktualisieren Sie einen Vektorvec1 in jedem Agenten funktionell mitassoc.Ändern Sie eine Matrixmat in jedem Agenten basierend auf dem vorhergehenden Vektor (d. h. die Matrix behält einen anderen Zustand bei).Aktualisieren Sie einen Vektorvec2 in jedem Agenten mitassoc basierend auf dem Zustand der in Schritt 2 erzeugten Matrix.

Zum Beispiel, wopersons ist eine Sequenz, möglicherweise faul (EDIT: Hinzugefügt äußeredoalls):

(doall
  (->> persons
    (map #(assoc % :vec1 (calc-vec1 %)))            ; update vec1 from person
    (map update-mat-from-vec1!)                     ; modify mat based on state of vec1
    (map #(assoc % :vec2 (calc-vec2-from-mat %))))) ; update vec2 based on state of mat

Alternative:

(doall
  (map #(assoc % :vec2 (calc-vec2-from-mat %))     ; update vec2 based on state of mat
       (map update-mat-from-vec1!                  ; modify mat based on state of vec1
            (map #(assoc % :vec1 (calc-vec1 %)) persons)))) ; update vec1 from person

Beachten Sie, dass der Status eines Agenten nicht vom Status eines Agenten abhängtandere Agent zu jedem Zeitpunkt. Muss ich hinzufügendoalls?

BEARBEITEN:Übersicht der Antworten zum 16.04.2014:

Ich empfehle, alle gegebenen Antworten zu lesen, aber es scheint, als ob sie sich widersprechen. Sie tun es nicht, und ich dachte, es könnte nützlich sein, wenn ich die Hauptideen zusammenfasse:

(1) Die Antwort auf meine Frage lautet "Ja": Wenn am Ende des von mir beschriebenen Prozesses die gesamte Lazy-Sequenz verwirklicht wird, wird für jedes Element in der richtigen Reihenfolge vorgegangen (1, 2, 3). Es besteht keine Notwendigkeit, sich zu bewerbendoall vor oder nach Schritt 2, in dem die Datenstruktur jedes Elements geändert wird.

(2) Aber: Das ist eine sehr schlechte Idee; Du fragst nach Ärger in der Zukunft. Wenn Sie irgendwann versehentlich die gesamte Sequenz oder einen Teil davon zu einem anderen Zeitpunkt als dem, den Sie ursprünglich beabsichtigt hatten, realisieren, kann sich herausstellen, dass die späteren Schritte Werte aus der Datenstruktur abrufen, die zum falschen Zeitpunkt dort abgelegt wurden. zu einem anderen Zeitpunkt als dem, den Sie erwarten. Der Schritt, der eine Datenstruktur pro Element mutiert, wird erst dann ausgeführt, wenn ein bestimmtes Element der verzögerten Sequenz erkannt wird. Wenn Sie dies also zur falschen Zeit feststellen, können Sie in späteren Schritten die falschen Daten abrufen. Dies könnte ein Fehler sein, der nur sehr schwer aufzuspüren ist. (Vielen Dank an @ A.Webb, der dieses Problem sehr deutlich gemacht hat.)

Antworten auf die Frage(4)

Ihre Antwort auf die Frage