Wandler sind Rezepte, was mit einer Datensequenz zu tun ist, ohne zu wissen, welche Sequenz zugrunde liegt (wie es geht). Es kann sich um eine beliebige Sequenz, einen asynchronen Kanal oder einen beobachtbaren Kanal handeln.
Sie sind zusammensetzbar und polymorph.
Der Vorteil ist, dass Sie nicht jedes Mal, wenn eine neue Datenquelle hinzugefügt wird, alle Standardkombinatoren implementieren müssen. Wieder und wieder. Als Ergebnis können Sie als Benutzer diese Rezepte in verschiedenen Datenquellen wiederverwenden.
Anzeigenaktualisierung
In der vorherigen Version 1.7 von Clojure hatten Sie drei Möglichkeiten, Datenflussabfragen zu schreiben:
- verschachtelte Aufrufe
(reduce + (filter odd? (map #(+ 2 %) (range 0 10))))
- funktionelle Zusammensetzung
(def xform
(comp
(partial filter odd?)
(partial map #(+ 2 %))))
(reduce + (xform (range 0 10)))
- Threading-Makro
(defn xform [xs]
(->> xs
(map #(+ 2 %))
(filter odd?)))
(reduce + (xform (range 0 10)))
Mit Wandlern schreiben Sie es wie folgt:
(def xform
(comp
(map #(+ 2 %))
(filter odd?)))
(transduce xform + (range 0 10))
Sie alle machen das Gleiche. Der Unterschied besteht darin, dass Sie Transducer niemals direkt aufrufen, sondern an eine andere Funktion übergeben. Wandler wissen, was zu tun ist, die Funktion, die Wandler erhält, weiß wie. Die Reihenfolge der Kombinatoren ist wie beim Schreiben mit einem Threading-Makro (natürliche Reihenfolge). Jetzt können Sie xform
mit Kanal wiederverwenden :
(chan 1 xform)
Wandler verbessern die Effizienz und ermöglichen es Ihnen, effizienten Code modularer zu schreiben.
Dies ist ein anständiger Durchlauf .
Im Vergleich zu Anrufen zu dem alten Komponieren
map
,filter
,reduce
usw. erhalten Sie eine bessere Leistung , weil Sie nicht brauchen , um zwischen den einzelnen Schritten Zwischen Sammlungen zu bauen, und wiederholt diese Sammlungen zu gehen.Im Vergleich zu
reducers
oder dem manuellen Zusammenstellen aller Vorgänge in einem einzigen Ausdruck können Sie Abstraktionen einfacher verwenden, die Modularität verbessern und die Verarbeitungsfunktionen wiederverwenden.quelle
map
/ mussreduce
Zwischensammlungen verwenden, da alle eine Iteratorkette bilden. Wo irre ich mich hier?map
undfilter
erstelle Zwischensammlungen, wenn sie verschachtelt sind.Wandler sind ein Kombinationsmittel zur Reduzierung von Funktionen.
Beispiel: Reduzierungsfunktionen sind Funktionen, die zwei Argumente annehmen: Ein bisheriges Ergebnis und eine Eingabe. Sie geben (bisher) ein neues Ergebnis zurück. Beispiel
+
: Mit zwei Argumenten können Sie sich das erste als Ergebnis und das zweite als Eingabe vorstellen.Ein Wandler könnte nun die + -Funktion übernehmen und daraus eine Doppel-Plus-Funktion machen (verdoppelt jeden Eingang, bevor er hinzugefügt wird). So würde dieser Wandler aussehen (in den grundlegendsten Begriffen):
Zur Veranschaulichung ersetzen Sie
rfn
durch, um+
zu sehen, wie+
sich in ein Plus-Doppel verwandelt:So
würde jetzt 12 ergeben.
Von Wandlern zurückgegebene Reduzierungsfunktionen sind unabhängig davon, wie das Ergebnis akkumuliert wird, da sie sich mit der an sie übergebenen Reduzierungsfunktion akkumulieren, ohne es zu wissen. Hier verwenden wir
conj
statt+
.Conj
Nimmt eine Sammlung und einen Wert und gibt eine neue Sammlung mit diesem angehängten Wert zurück.würde ergeben [2 4 6]
Sie sind auch unabhängig davon, um welche Art von Quelle es sich handelt.
Mehrere Wandler können als (verkettbares) Rezept verkettet werden, um reduzierende Funktionen zu transformieren.
Update: Da es jetzt eine offizielle Seite darüber gibt, empfehle ich dringend, sie zu lesen: http://clojure.org/transducers
quelle
double
undtransduce
?Angenommen, Sie möchten eine Reihe von Funktionen verwenden, um einen Datenstrom zu transformieren. Mit der Unix-Shell können Sie so etwas mit dem Pipe-Operator tun, z
(Der obige Befehl zählt die Anzahl der Benutzer, deren Benutzername den Buchstaben r in Groß- oder Kleinbuchstaben enthält.) Dies wird als eine Reihe von Prozessen implementiert, von denen jeder aus der Ausgabe der vorherigen Prozesse liest, sodass vier Zwischenströme vorhanden sind. Sie können sich eine andere Implementierung vorstellen, die die fünf Befehle zu einem einzigen Aggregatbefehl zusammensetzt, der genau einmal aus seiner Eingabe liest und seine Ausgabe schreibt. Wenn Zwischenströme teuer und die Zusammensetzung billig wären, könnte dies ein guter Kompromiss sein.
Das Gleiche gilt für Clojure. Es gibt mehrere Möglichkeiten, eine Pipeline von Transformationen auszudrücken. Je nachdem, wie Sie dies tun, können Zwischenströme von einer Funktion zur nächsten übertragen werden. Wenn Sie viele Daten haben, ist es schneller, diese Funktionen zu einer einzigen Funktion zusammenzufassen. Wandler machen das einfach. Eine frühere Clojure-Innovation, Reduzierungen, lässt Sie dies ebenfalls tun, jedoch mit einigen Einschränkungen. Wandler beseitigen einige dieser Einschränkungen.
Um Ihre Frage zu beantworten, machen Wandler Ihren Code nicht unbedingt kürzer oder verständlicher, aber Ihr Code wird wahrscheinlich auch nicht länger oder weniger verständlich sein, und wenn Sie mit vielen Daten arbeiten, können Wandler Ihren Code machen schneller.
Dies ist eine ziemlich gute Übersicht über Wandler.
quelle
pmap
, was nicht genug Aufmerksamkeit zu bekommen scheint. Wenn Siemap
eine teure Funktion über eine Sequenz pingen, ist die parallele Operation so einfach wie das Hinzufügen von "p". Sie müssen nichts anderes in Ihrem Code ändern und es ist jetzt verfügbar - nicht Alpha, nicht Beta. (Wenn die Funktion Zwischensequenzen erstellt, sind die Wandler möglicherweise schneller, denke ich.)Rich Hickey hielt auf der Strange Loop 2014-Konferenz (45 Minuten) einen Vortrag über „Transducers“.
Er erklärt auf einfache Weise, was Wandler sind, anhand von Beispielen aus der Praxis - der Verarbeitung von Taschen auf einem Flughafen. Er trennt die verschiedenen Aspekte klar voneinander und kontrastiert sie mit den aktuellen Ansätzen. Gegen Ende gibt er die Gründe für ihre Existenz an.
Video: https://www.youtube.com/watch?v=6mTbuzafcII
quelle
Ich habe festgestellt, dass das Lesen von Beispielen von Transducers-js mir hilft, sie konkret zu verstehen, wie ich sie im täglichen Code verwenden könnte.
Betrachten Sie zum Beispiel dieses Beispiel (entnommen aus der README-Datei unter dem obigen Link):
Zum einen
xf
sieht die Verwendung viel sauberer aus als die übliche Alternative mit Underscore.quelle
t.into([], t.comp(t.map(inc), t.filter(isEven)), [0,1,2,3,4])
Wandler sind (nach meinem Verständnis!) Funktionen, die eine Reduktionsfunktion übernehmen und eine andere zurückgeben. Eine reduzierende Funktion ist eine, die
Beispielsweise:
In diesem Fall übernimmt my-transducer eine Eingangsfilterfunktion, die auf 0 angewendet wird. Wenn dieser Wert gerade ist? Im ersten Fall übergibt der Filter diesen Wert an den Zähler und filtert dann den nächsten Wert. Anstatt zuerst zu filtern und dann alle diese Werte zu übergeben, um zu zählen.
Es ist dasselbe wie im zweiten Beispiel, in dem jeweils ein Wert überprüft wird. Wenn dieser Wert kleiner als 3 ist, können Sie 1 addieren.
quelle
Eine klare Definition des Wandlers finden Sie hier:
Um es zu verstehen, betrachten wir das folgende einfache Beispiel:
Was ist damit, wir wollen wissen, wie viele Kinder im Dorf sind? Wir können es leicht mit dem folgenden Reduzierer herausfinden:
Hier ist eine andere Möglichkeit:
Außerdem ist es sehr leistungsfähig, wenn auch Untergruppen berücksichtigt werden. Wenn wir zum Beispiel wissen möchten, wie viele Kinder in der Familie Brown sind, können wir Folgendes ausführen:
Ich hoffe, Sie finden diese Beispiele hilfreich. Mehr finden Sie hier
Ich hoffe es hilft.
Clemencio Morales Lucas.
quelle
Ich habe darüber mit einem Clojurescript- Beispiel gebloggt, das erklärt, wie die Sequenzfunktionen jetzt erweiterbar sind, indem die Reduktionsfunktion ersetzt werden kann.
Dies ist der Punkt der Wandler, wie ich es lese. Wenn Sie an die
cons
oder -Operation denken, dieconj
in Operationen wie usw. fest codiert istmap
,filter
war die Reduzierungsfunktion nicht erreichbar.Bei Wandlern ist die Reduktionsfunktion entkoppelt und ich kann sie
push
dank Wandlern wie beim nativen Javascript-Array ersetzen .filter
und Freunde haben eine neue 1-Arity-Operation, die eine Wandlerfunktion zurückgibt, mit der Sie Ihre eigene Reduktionsfunktion bereitstellen können.quelle
Hier ist meine (meistens) jargon- und codefreie Antwort.
Stellen Sie sich Daten auf zwei Arten vor: als Stream (Werte, die im Laufe der Zeit auftreten, z. B. Ereignisse) oder als Struktur (Daten, die zu einem bestimmten Zeitpunkt vorhanden sind, z. B. eine Liste, ein Vektor, ein Array usw.).
Es gibt bestimmte Vorgänge, die Sie möglicherweise über Streams oder Strukturen ausführen möchten. Eine solche Operation ist das Mapping. Eine Zuordnungsfunktion kann jedes Datenelement (vorausgesetzt, es ist eine Zahl) um 1 erhöhen, und Sie können sich hoffentlich vorstellen, wie dies entweder auf einen Stream oder eine Struktur angewendet werden könnte.
Eine Zuordnungsfunktion ist nur eine aus einer Klasse von Funktionen, die manchmal als "Reduktionsfunktionen" bezeichnet werden. Eine weitere häufig verwendete Reduktionsfunktion ist der Filter, mit dem Werte entfernt werden, die mit einem Prädikat übereinstimmen (z. B. alle geraden Werte entfernen).
Mit Wandlern können Sie eine Folge von einer oder mehreren reduzierenden Funktionen "umschließen" und ein "Paket" (das selbst eine Funktion ist) erstellen, das sowohl für Streams als auch für Strukturen funktioniert. Zum Beispiel könnten Sie eine Folge von Reduzierungsfunktionen "verpacken" (z. B. gerade Zahlen filtern und dann die resultierenden Zahlen zuordnen, um sie um 1 zu erhöhen) und dann dieses "Paket" des Wandlers entweder für einen Stream oder eine Wertestruktur (oder für beide) verwenden. .
Was ist das Besondere daran? In der Regel können reduzierende Funktionen nicht effizient zusammengesetzt werden, um sowohl an Streams als auch an Strukturen zu arbeiten.
Der Vorteil für Sie besteht also darin, dass Sie Ihr Wissen über diese Funktionen nutzen und auf weitere Anwendungsfälle anwenden können. Die Kosten für Sie sind, dass Sie einige zusätzliche Maschinen (dh den Wandler) erlernen müssen, um diese zusätzliche Leistung zu erhalten.
quelle
Soweit ich weiß, sind sie wie Bausteine , die von der Eingabe- und Ausgabeimplementierung entkoppelt sind. Sie definieren nur die Operation.
Da die Implementierung der Operation nicht im Code der Eingabe enthalten ist und mit der Ausgabe nichts unternommen wird, sind Wandler äußerst wiederverwendbar. Sie erinnern mich an Flow s in Akka Streams .
Ich bin auch neu bei Schallköpfen, entschuldige die möglicherweise unklare Antwort.
quelle
Ich finde, dieser Beitrag gibt Ihnen eine bessere Vogelperspektive auf den Schallkopf.
https://medium.com/@roman01la/understanding-transducers-in-javascript-3500d3bd9624
quelle