Sunday 26 March 2017

Umzugsdurchschnitt Clojure

An diesem Wochenende habe ich mich entschlossen, meine Hand bei Scala und Clojure auszuprobieren, ich bin mit objektorientierter Programmierung kompetent, und so war Scala einfach als Sprache abholen, wollte aber funktionale Programmierung ausprobieren. Hier ist es hart. Ich kann es nur T scheinen, um meinen Kopf in eine Art des Schreibens von Funktionen Als ein Experte funktionale Programmierer, wie kommen Sie ein Problem. Gezigt eine Liste von Werten und eine definierte Periode der Summation, wie würden Sie generieren eine neue Liste der einfachen gleitenden Durchschnitt von Die Liste. Für Beispiel Bei den Listenwerten 2 0, 4 0, 7 0, 6 0, 3 0, 8 0, 12 0, 9 0, 4 0, 1 0 und der Periode 4 sollte die Funktion 0 0 zurückgeben , 0 0, 0 0, 4 75, 5 0, 6 0, 7 25, 8 0, 8 25, 6 5. Nach dem Verbringen eines Tages, der es übermacht, das Beste, was ich in Scala kommen könnte, war das. Ich weiß Das ist schrecklich ineffizient, ich mache lieber etwas wie. Jetzt würde das in einem imperativen Stil leicht gemacht werden, aber ich kann t für das Leben von mir ausarbeiten, wie man das funktionell aussagt. Interesting Problem kann ich an viele Lösungen denken, Mit unterschiedlichem Wirkungsgrad, um das Zeug wiederholt hinzuzufügen, ist nicht wirklich ein Leistungsproblem, aber lassen Sie es annehmen, dass es auch ist, die Nullen am Anfang können später vorbereitet werden, also lasst uns nicht darum kümmern, sie zu produzieren Wenn der Algorithmus ihnen natürlich zur Verfügung stellt, Gut, wenn nicht, korrigieren wir es später. Starting mit Scala 2 8, die folgenden würde das Ergebnis für n Periode geben, indem man gleitend, um ein Schiebefenster der Liste zu bekommen. Trotzdem, obwohl dies ziemlich elegant ist, hat es nicht das Beste Leistung möglich, weil es nicht von Vorteil bereits berechneten Ergänzungen Also, von ihnen zu sprechen, wie können wir sie bekommen. Lassen wir sagen, wir schreiben dies. Wir haben eine Liste der Summe von jedem zwei Paare Lassen Sie uns versuchen, dieses Ergebnis zu verwenden Um den gleitenden Durchschnitt von 4 Elementen zu berechnen Die obige Formel hat die folgende Berechnung gemacht. So, wenn wir jedes Element nehmen und es dem zweiten nächsten Element hinzufügen, erhalten wir den gleitenden Durchschnitt für 4 Elemente. Wir können es so machen. Wir könnten dann Berechnen Sie den gleitenden Durchschnitt für 8 Elemente, und so weiter Nun, es gibt einen bekannten Algorithmus, um Dinge zu berechnen, die einem solchen Muster folgen. Es ist am meisten bekannt für seine Verwendung bei der Berechnung der Macht einer Zahl Es geht wie folgt. So, lassen Sie sich bewerben Es hier. So, hier s die Logik Periode 0 ist ungültig, Periode 1 ist gleich der Eingabe, Periode 2 ist Schiebefenster von Größe 2 Wenn größer als das, kann es sogar oder ungerade. Wenn seltsam, fügen wir jedes Element zu Das MovingSum der nächsten ungeraden - 1 Elemente Zum Beispiel, wenn 3, fügen wir jedes Element dem MovingSum der nächsten 2 Elemente hinzu. Wenn wir sogar das MovingSum für n 2 berechnen, dann addiere jedes Element zu den folgenden n 2 Schritten. Mit dieser Definition können wir dann wieder auf das Problem zurückgreifen und dies tun. Es gibt eine leichte Ineffizienz in Bezug auf die Verwendung von aber es s o Periode, nicht Es kann effizienter mit einem Schwanz rekursive Funktion gemacht werden Und natürlich die Definition von Schieben, die ich zur Verfügung gestellt habe, ist schrecklich leistungsstark, aber es wird eine viel bessere Definition von es auf Scala 2 8 Beachten Sie, dass wir t machen eine effiziente Schiebe-Methode auf einer Liste, aber wir können es auf einem Iterable. Having sagte alle Dass ich mit der allerersten Definition gehe und nur dann optimiere, wenn eine kritische Pfadanalyse dies als eine große Sache erkannt hat. Um zu schließen, lasst man überlegen, wie ich über das Problem ging Wir haben ein gleitendes durchschnittliches Problem Ein gleitender Durchschnitt ist die Summe Von einem bewegenden Fenster auf einer Liste, geteilt durch die Größe dieses Fensters Also, zuerst, ich versuche, ein Schiebefenster zu bekommen, Summe alles darauf und dann durch die Größe zu teilen. Das nächste Problem war, Wiederholung von bereits berechneten Ergänzungen zu vermeiden In diesem Fall ging ich zur kleinsten Ergänzung, und ich versuchte herauszufinden, wie man größere Summen berechnen kann, um solche Ergebnisse wiederzuverwenden. Schließlich lasst man versuchen, das Problem so zu lösen, wie du es gedacht hast, indem du das vorherige Ergebnis addierst und subtrahierst Der erste Durchschnitt ist einfach. Jetzt machen wir zwei Listen Zuerst wird die Liste der Elemente subtrahiert Als nächstes wird die Liste der Elemente hinzugefügt werden. Wir können diese beiden Listen mit Zip hinzufügen Diese Methode wird nur produzieren so viele Elemente wie die kleineren Liste hat, die das Problem der Subtraktion größer als nötig vermeidet. Wir beenden durch Komponieren des Ergebnisses mit einer fold. which ist die Antwort zurückzugeben Die ganze Funktion sieht so aus. Ich kenne Clojure besser als Scala, also hier geht wie ich Schreibe dies die andere Clojure Eintrag hier ist zwingend, dass s nicht wirklich, was Sie nach und isn t idiomatic Clojure Der erste Algorithmus, der mir in den Sinn kommt, nimmt wiederholt die angeforderte Anzahl von Elementen aus der Sequenz, fällt das erste Element und wiederkehrende. Die folgenden Arbeiten auf jede Art von Sequenz Vektor oder Liste, faul oder nicht und gibt eine faulen Reihenfolge von Durchschnittswerten --- was könnte hilfreich sein, wenn Sie arbeiten auf einer Liste von unbestimmten Größe Beachten Sie, dass es kümmert sich um die Basis Fall implizit Rückkehr nil wenn es aren t genug Elemente in der Liste zu konsumieren. Running dies auf Ihre Testdaten ergibt. It doesn t geben 0 für die ersten paar Elemente in der Sequenz, obwohl das könnte leicht etwas künstlich behandelt werden. Die einfachste Sache von allen Ist zu sehen, das Muster und in der Lage sein, in Erinnerung zu bringen, eine verfügbare Funktion, die passt die Rechnung Partition gibt eine faulen Blick auf Teile einer Sequenz, die wir dann abbilden können. Jemand fragte nach einem Schwanz rekursive Version Schwanz Rekursion vs Faulheit ist ein Ein bisschen ein Kompromiss Wenn dein Job eine Liste aufbaut, dann macht deine Funktion Schwanz rekursiv ist in der Regel ziemlich einfach, und das ist keine Ausnahme --- nur aufbauen die Liste als Argument für eine Unterfunktion Wir sammeln zu einem Vektor statt Eine Liste, denn sonst wird die Liste rückwärts aufgebaut werden und muss am Ende umgekehrt werden. Hop ist ein Weg, um eine anonyme innere Funktion Art wie Scheme s namens let recur muss in Clojure verwendet werden, um Schwanz Anrufe konjizieren zu beseitigen ist Eine verallgemeinerte Verabredung in der Art und Weise natürlich für die Sammlung --- der Beginn der Listen und das Ende der Vektoren. answered Aug 24 09 bei 2 58. Ich habe beschlossen, zu diesem alten Q hinzuzufügen, weil das Thema kam wieder und ich Finde es vorzuziehen, auf diese schöne Sammlung von möglichen Lösungen zu verweisen, während ich meine eigene Aufnahme hinzufüge, die sich von früheren Versionen in Clojure unterscheidet, wie es in der A erklärt wird. Vielleicht können wir das umfangreichste Repository der funktionalen mov-avg-Implementierungen - Micha Marczyk - aufbauen Mar 2 10 bei 0 20.Hier sa teilweise punktfrei eine Zeile Haskell Lösung. Erste es gilt Schwänze auf die Liste, um die Schwänze Listen, so. Reverses es und fällt die ersten p Einträge nehmen p als 2 hier. Falls Sie Aren t vertraut mit dem Punktnippel-Symbol, es ist der Operator für funktionale Komposition, dh es übergibt die Ausgabe einer Funktion als Eingang eines anderen, komponiert sie zu einer einzigen Funktion gf bedeutet, f auf einen Wert zu setzen und dann den Ausgang an g weiterzugeben , So fgx ist das gleiche wie gfx Im Allgemeinen führt seine Verwendung zu einer klareren Programmierung style. It dann ordnet die Funktion ausIntegral p sum nehmen p auf die Liste Also für jede Liste in der Liste nimmt es die ersten p Elemente, summiert sie, dann teilt Sie von p Dann klopfen wir einfach die Liste wieder mit Reverse. This alle sieht viel mehr ineffizient als es umgekehrt doesn t körperlich umgekehrt die Reihenfolge einer Liste, bis die Liste ausgewertet wird, es legt es einfach auf den Stapel gut ol Lazy Haskell Schwänze auch nicht alle diese separaten Listen, es nur verweist auf verschiedene Abschnitte der ursprünglichen Liste Es ist immer noch keine gute Lösung, aber es eine Zeile long. Here eine etwas schönere, aber längere Lösung, die mapAccum verwendet, um eine gleitende Subtraktion zu tun Und zusätzlich. First wir teilen die Liste in zwei Teile bei p, so. Sum das erste Bit. Zip das zweite Bit mit der ursprünglichen Liste dies nur paar Artikel aus der Reihenfolge aus den beiden Listen Die ursprüngliche Liste ist offensichtlich länger, aber wir verlieren Dieses extra bit. Jetzt definieren wir eine Funktion für unsere mapAccum ulator mapAccumL ist die gleiche wie Karte, aber mit einem extra laufenden Zustand Akkumulator Parameter, die von der vorherigen Zuordnung an die nächste übergeben wird, wie Karte läuft durch die Liste Wir verwenden den Akkumulator Als unser gleitender Durchschnitt, und da unsere Liste aus dem Element besteht, das gerade das Schiebefenster verlassen hat und das Element, das gerade in die Liste eingegangen ist, die wir gerade gezippt haben, nimmt unsere Schiebefunktion die erste Zahl x weg vom Durchschnitt und fügt den zweiten hinzu Zahl y Wir passieren dann die neuen s entlang und kehren s geteilt durch p snd Sekunden nimmt nur das zweite Mitglied eines Paares Tupel, das verwendet wird, um den zweiten Rückgabewert von mapAccumL zu nehmen, als mapAccumL wird den Akkumulator sowie die zugeordneten zurückgeben List. For diejenigen von Ihnen nicht vertraut mit dem Symbol ist es der Anwendungs-Operator Es doesn t wirklich alles tun, aber es hat eine hat eine niedrige, rechts-assoziative verbindliche Vorrang, so bedeutet es, dass Sie die Klammern nehmen können, nehmen Sie LISPers, iefx ist Das gleiche wie f x. Running ma 4 2 0, 4 0, 7 0, 6 0, 3 0, 8 0, 12 0, 9 0, 4 0, 1 0 ergibt 4 75, 5 0, 6 0, 7 25 , 8 0, 8 25, 6 5 für beide Lösung. Oh und du musst die Modulliste importieren, um eine Lösung zu kompilieren. Daniel Danke Schreibcode ist viel einfacher als es zu erklären - Sie haben das Wesentliche beschrieben Zwei Lists Streams werden in beiden Funktionen beibehalten und bekommen ihre Köpfe bei jeder Iteration abgenommen One List Stream dient als die Hauptsammlung, um durchzuleiten, während die anderen List Stream, die die gleiche Sammlung ist, außer hat die Periode weniger Doubles genommen, wird bei der Berechnung des neuen gleitenden Durchschnittes Walter Chang am 24. August um 17 19 verwendet. Die J Programmiersprache erleichtert Programme wie gleitender Durchschnitt In der Tat gibt es Weniger Zeichen in als in ihrem Etikett, gleitender Durchschnitt. Für die Werte in dieser Frage einschließlich der Namen Werte hier ist ein einfacher Weg, um dies Code. Wir können dies beschreiben, indem Sie Etiketten für Komponenten. Bei Beispiele verwenden genau das gleiche Programm Die einzige Unterschied ist die Verwendung von mehr Namen in der zweiten Form Solche Namen können Leser helfen, die don t kennen die J Primaries. Let s Blick ein bisschen weiter in das, was los ist in der Unterprogramm, durchschnittlich bedeutet Summation und bezeichnet Division wie das klassische Zeichen Berechnung Eine Tally-Zählung von Items wird durch das Gesamtprogramm durchgeführt, dann ist die Summe von Werten geteilt durch die Tally von Werten. Das Ergebnis der gleitenden Durchschnitt Berechnung hier nicht enthalten die führenden Nullen in der ursprünglichen Frage erwartet Diese Nullen sind Wohl nicht Teil der beabsichtigten Berechnung. Die hier verwendete Technik wird als stillschweigende Programmierung bezeichnet. Es ist so ziemlich das gleiche wie die punktfreie Art der funktionalen Programmierung. answered Aug 26 10 at 16 15.Hier ist Clojure vorgibt, eine funktionellere Sprache zu sein Dies ist völlig schwanzrekursiv, btw, und enthält führende Nullen. Usually habe ich die Sammlung oder Liste Parameter zuletzt, um die Funktion leichter zu Curry Aber in Clojure. is so umständlich, ich in der Regel am Ende tun dies in diesem Fall, es Doesn t wirklich egal welche bestellen die Parameter go. answered Aug 24 09 bei 4 56.Hi Jonathan, ich bin ziemlich neu in dieser funktionalen Programmierung, könnten Sie mir bitte erklären, wie dies ist tail-rekursive Danke James P Aug 24 09 bei 14 38. Die Rekursion geschieht auf der if-Anweisung, wobei jede Option auf recur basiert. Dies wird jeden Parameter zuerst berechnen und erst dann wiederkehren. Die Antwort wird das Ergebnis von recur sein. Als Ergebnis ergibt sich das gleiche Ergebnis, das von der Rekursion zurückgegeben wird Andere Berechnungen, das ist Schwanz rekursiv Daniel C Sobral Aug 24 09 at 15 20.Dieses Beispiel nutzt den Zustand, da für mich ist es eine pragmatische Lösung in diesem Fall und eine Schließung, um die Fenster-Mittelung Funktion zu schaffen. Es ist immer noch funktional in Der Sinn für die Verwendung von erstklassigen Funktionen, obwohl es nicht Nebenwirkung frei ist Die beiden Sprachen, die Sie erwähnten, laufen beide auf der JVM und damit beide erlauben staatlichen Management, wenn nötig. answered Aug 24 09 bei 1 55. Dies ist möglich Lösung ist in Haskell, die mir mehr vertraut ist. Erweiterte Aug 24 09 bei 10 23. Ich mag die Verwendung der Match-Anweisung Ich habe versucht, etwas Ähnliches zu machen, aber konnte nicht ganz den ganzen Weg dort James P Aug 24 09 an 14 39. Eine kurze Clojure-Version, die den Vorteil hat, O-Listenlänge unabhängig von deiner Periode zu sein. Dies macht die Tatsache aus, dass du die Summe eines Zahlenbereichs berechnen kannst, indem du eine kumulative Summe der Sequenz zB 1 2 3 4 5 schaffst - 0 1 3 6 10 15 und dann subtrahieren Sie die beiden Zahlen mit einem Offset gleich Ihrer Periode. Being spät auf der Party, und neue zu funktionalen Programmierung auch, kam ich zu dieser Lösung mit einer inneren Funktion. Ich habe die Idee, zu Teilen die ganze Liste durch den Zeitraum len im Voraus Dann generiere ich die Summe, um mit den Len-First-Elementen zu beginnen und ich generiere die ersten, ungültigen Elemente 0 0, 0 0. Dann rekultiviere ich rekursiv die erste und füge den letzten Wert hinzu Am Ende liste ich das Ganze auf, das am 29. April 10 um 19 Uhr im Haskell Pseudocode. Jetzt sollte man wirklich die 4 out. answered Jul 23 13 bei 13 45. Die Taste ist die Schwänze Funktion, die eine Liste auf eine Liste der Kopien der ursprünglichen Liste, mit der Eigenschaft, dass die n-ten Element des Ergebnisses Fehlt die ersten n-1 Elemente. Wir wenden fmap avg nehmen n auf das Ergebnis, was bedeutet, dass wir die n-Länge Präfix aus der Unterliste nehmen und berechnen ihre avg Wenn die Länge der Liste, die wir sind, ist nicht n, Dann berechnen wir nicht den Durchschnitt, da es undefiniert ist. In diesem Fall kehren wir nichts zurück, wenn es ist, wir tun und wickeln es in Gerade endlich laufen wir catMaybes auf das Ergebnis von fmap avg nehmen n, um loszuwerden, die vielleicht Type. answered Oct 21 13 at 1 29. Ich war überrascht und enttäuscht von der Aufführung dessen, was mir die idiomatischsten Clojure-Lösungen erschien, JamesCunningham s lazy-seq solutions. So hier eine Kombination von James-Lösung mit der Idee, Exponentiation to moving sums. Edit this one - basiert auf mikera s Lösung - ist noch schneller. answered Jul 22 13 bei 19 21.Your Antwort.2017 Stack Exchange, Inc. Clojure Programmierung von Beispiel. Dies ist beabsichtigt, eine Hand auf zuerst sein Schau auf Clojure Wenn du die Beispiele ausprobieren möchtest, dann möchtest du vielleicht schon eine Arbeitsumgebung eingerichtet haben, so dass du die Ergebnisse des Beispielcodes sehen kannst. Clojure-Programme werden in Formularen geschrieben. In der Klammer enthaltene Formulare zeigen an Function calls. calls die Funktion mit Argumenten 1 2 3 und gibt den Wert 6, die Summe der Argumente. Neue Funktionen können mit defn definiert werden. Hier x und y sind Symbole, die die Eingabe-Argumente Funktion ist aufgerufen, um die Summe von x und teilen Y durch 2 Beachten Sie, dass die Formulare immer in der Präfix-Notation sind, mit der Funktion, die durch nachfolgende Argumente gefolgt wird. Jetzt kann der Mittelwert als andeando aufgefordert werden. 4 In diesem Beispiel ist der Durchschnitt ein Symbol, dessen Wert eine Funktion für eine detaillierte Erläuterung ist Forms. Clojure bietet einfachen Zugriff auf die JVM. This ruft die Show-Methode auf das Ergebnis, von denen konstruiert eine neue Jframe Beachten Sie den vollständigen Stop vor dem Methodenaufruf und die volle Haltestelle nach der Konstruktion beziehen sich auf. Funktionen können an andere Funktionen übergeben werden. Kehrt zurück 5 7 9 Karte ist eine Funktion, die eine andere Funktion annimmt und sie mit Argumenten aus folgenden Sammlungen anruft. In unserem Fall haben wir die Funktion und zwei Vektoren von ganzen Zahlen zur Verfügung gestellt. Das Ergebnis ist eine Liste der Ergebnisse des Aufrufs mit Argumenten aus den Vektoren Die Verwendung von Funktionen als Argumente für andere Funktionen ist sehr leistungsfähig Wir können unsere vorher definierte Mittelfunktion mit der Karte wie so verwenden. Rückmeldungen 5 2 7 2 9 2 Wir sehen hier, dass Clojure die Verhältnisse als Datentypen für eine vollständige Liste verweist. Funktionen können Auch addiere andere functions. Here addx gibt eine neue Funktion zurück, die 1 Argument annimmt und addiert x zu it. returns eine Funktion, die mit 1 Argument aufgerufen werden kann und fügt hinzu 5 zu it. returns 6 7 8 9 10 Wir nannten Karte mit a Das Ergebnis von addx, das war eine Funktion, die ein Argument annimmt und fügt hinzu 5 Diese Funktion wurde auf die Liste der Zahlen, die wir geliefert haben. Es gibt eine kurze Hand, um eine unbenannte Funktion zu erstellen. Will erstellen eine Funktion, die mit zwei Argumenten 1 und 2.Will fügen Sie 5 zu der Liste der Zahlen hinzu, die wir geliefert haben. Die Fähigkeit, dynamisch zu vergeben und zu erstellen, wird als erstklassige Funktionen bezeichnet. Die fungale Programmierung behandelt die Berechnung als mathematische Auswertung und vermeidet staatliche und veränderliche Daten In einer zwingenden Sprache, die Sie haben Würde typischerweise Variablen erstellen und ihren Wert regelmäßig ändern In Clojure kehren Sie neue Ergebnisse zurück, ohne zu modifizieren, was vorher war. Abweichungen ohne Nebenwirkungen Edit. Function Nebenwirkungen können die Werte von Eingaben ändern, globale Daten ändern oder IO. Imperative void ausführen Moveplayer p, x, y. updates ein Spielerobjekt mit einem neuen location. Object Oriented class player. again, mutiert ein bestehendes object. Functional moveplayer oldp x ya komplett neuer Spieler wird zurückgegeben, der alte Spieler ist nicht betroffen. Imperativ Sie nur wissen Dass p hat sich geändert, weil der Funktionsname es hinweist Und es könnte andere Dinge wie einige Welt-Daten geändert haben In FP oldp ist bewahrt Sie don t müssen sich Sorgen darüber, was passiert es oder die Welt - nichts kann sich ändern und es ist Explizit, dass ein neuer Spieler als Folge des Umzugs zurückgegeben wird. Die Hauptvorteile hier sind Argumentation, Testbarkeit und Parallelität Die Sprache erzwingt, dass es keine Nebenwirkungen gibt, so dass Sie das Verhalten vermitteln können Inputs direkt auf Ausgänge, die es einfacher zu konstruieren und machen Denken Sie an Testfälle Zwei Threads können gleichzeitig auf den gleichen Daten arbeiten, ohne dass sie sich nicht gegenseitig verderben, da die Daten nicht geändert werden. Wenn Sie einen Artikel aus einer Liste entfernen möchten, würde die imperative Lösung die Liste ändern. Eine funktionale Lösung wäre Geben Sie eine völlig neue Liste, so dass das Original an Ort und Stelle Das klingt auf der Oberfläche, um verschwenderisch zu sein, aber es gibt viele Möglichkeiten, dass dies durch den Compiler optimiert wird sehr effizient. Code ohne Variablen für jemanden verwendet, um imperative Programmierung kann ein wenig nehmen Immer gewohnt Hier ist eine kurze Anleitung zur Umwandlung von variablen Stil-Code in funktionalen Code. Sie wollen einige Änderungen zu bearbeiten Edit. Rarrange diese Art von Sachen in eine Form, die keine Variablen erfordert. Bereich 1 100 2 erzeugt eine faule Sequenz von Zahlen 1 3 5 7 99 1 ist der Ausgangspunkt, 100 ist der Endpunkt, 2 ist der Schritt reduzieren Anrufe die Funktion Zuerst ruft er mit zwei Argumenten, die ersten beiden Zahlen, die von Bereich geliefert werden Es ruft wieder mit dem vorherigen Ergebnis und der nächsten Nummer, bis alle Zahlen erschöpft sind Clojure hat viel Unterstützung für Sequenzen, Sammlungen und High-Level-Operationen Wie Sie sie lernen, finden Sie sehr ausdrucksvolle Möglichkeiten, um Aufgaben wie diese zu schreiben Wollen, iterieren, stattdessen verwenden Sie die Loop Recur Konstrukt Editiert die Fakultät von 5 Das Loop-Spezialformular bindet Bindungen, gefolgt von Ausdrücken, die ausgewertet werden sollen In diesem Beispiel ist 5 an i gebunden und 1 ist an acc gebunden. Wenn das Sonderformular dann prüft, ob ich bin Gleich null Da ist es nicht gleich 0, recur rebinds neue Werte an i und acc vor der Rückkehr der Kontrolle zurück an die Spitze der Schleife, um den Körper seiner Ausdrücke neu zu bewerten A dekrementiert i dec i ist Rebound an i und die Produkt von acc und i acc i ist Rebound zu acc Diese Schleife wird rekursiv aufgerufen, bis i gleich 0 acc speichert das Ergebnis der Multiplikation jedes Wertes Ich nahm Beachten Sie, dass eine Bindung verhält sich wie eine Variable. Auch Recur kann entweder eine Schleife oder Funktion Definition . Im obigen Beispiel kann die faktorielle Funktion entweder 1 Argument n nehmen, was zur Auswertung führt. Bei der Lieferung von 2 Argumenten ergibt sich eine Auswertung von. recur ist wichtig, weil sie die Funktionseingaben anstelle des Hinzufügens eines rekursiven Aufrufs an die Stack Hätten wir stattdessen faktorielles Zählwerk verwendet, hätten wir ein ähnliches Verhalten, aber für große Werte von n können Sie einen Stapelüberlauf verursachen. Beachten Sie auch, dass wir zwei Definitionen für faktorielle, eins mit einem Argument und ein anderes mit zwei Argumenten eingeführt haben Der Benutzer ruft die eine Argumentversion auf, die in das zwei Argumentformular für die Auswertung übersetzt wird. Die Arität einer Funktion ist die Anzahl der Argumente, die die Funktion übernimmt. Natürlich hätten wir eine noch einfachere Definition ähnlich der vorherigen Summe des ungeraden Beispiels schreiben können. Sie müssen ein Ergebnis speichern und es mehrfach verwenden Edit. There ist ein nützliches Makro, das ein Symbol an einen Wert für die lokale Verwendung bindet. Hiermit wird eine zufällige Zahl zwischen 0 und 0 8 erzeugt, 0 2 wird hinzugefügt, Und das Ergebnis ist an das Symbol gebunden g Eine Farbe wird mit rot-grünen blauen Werten von g konstruiert, die eine graue Skala von Intensität von 0 2 bis 1 sein wird. Sie möchten mehrere Methodenaufrufe auf demselben Objekt bearbeiten Edit. Using Java-Bibliotheken bringen Sie oft in eine Situation, in der Sie eine lokale Variable verwenden möchten. Denken Sie daran, doto Die große Sache über doto ist, dass es das Objekt zurückgibt, nachdem mehrere Anrufe angewendet wurden. Messing permanente Statusvariablen Edit. Clojure unterstützt viele veränderliche Typen, aber es Ist wichtig, um den Unterschied zwischen ihnen zu kennen und wie sie sich verhalten Die angebotenen Typen sind Refs, Agenten, Atome und Vars. Refs sind wie Ref-Zellen in ML, Boxen in Scheme oder Zeiger in anderen Sprachen Es ist eine Box, die Sie ändern können Der Inhalt von Aber im Gegensatz zu den anderen Sprachen ist die Torsion, dass man nur die Veränderung innerhalb einer Transaktion machen kann. Dies stellt sicher, dass zwei Threads keinen Konflikt haben können, wenn sie aktualisieren oder auf das zugreifen, was in den ref. declares r gespeichert ist Anfangswert von nil. sets r bis 5 in einer Transaktion. Geben Sie den Wert von r, das ist 5 Beachten Sie, dass r ist Kurzschrift für Deref r, und arbeitet mit allen Clojures mutable Typen r selbst ist ein ref, kein Wert. Agents Edit. Agents werden durch Funktionen asynchron geändert. Sie senden eine Funktion an den Agenten, die später diese Funktion auf ihren aktuellen Wert anwenden wird. Es ist asynchron, weil der Aufruf zum Senden sofort zurückkehrt. Die Funktion wird in einem Thread-Pool zur Ausführung in die Warteschlange gestellt Zugriff auf Multithreading. In diesem Beispiel haben wir einen Agenten mit dem Anfangswert 1 definiert. Wir haben den Agenten eine Funktion inc geschrieben, die sein Argument inkrementiert. Jetzt senden Warteschlangen, die für die Ausführung durch einen Threadpool warten, wird beendet, bis alle Funktionen, die auf einem Agenten ausstehend sind Hat einen Wert zurückgesetzt, der den Wert unseres Agenten, der jetzt 2 ist, weil 1 inkrementiert wurde. Atome werden durch Funktionen synchron geändert Sie rufen Swap und die Funktion, die Sie liefern, wird auf den Wert des Atoms angewendet, bevor Swap returns. Hinweis, dass Swap zurückgibt Das Ergebnis der Funktion, die auf den aktuellen Atomwert angewendet wurde Refs sind koordiniert, während Agenten und Atome unkoordiniert sind. Dies bedeutet, dass in einer Multithread-Umgebung Refs in einer Transaktion modifiziert werden, die sicherstellt, dass nur ein Thread den Wert an a ändern kann Zeit Wo Atome und Agenten Warteschlangen ändern Änderungsfunktionen, um sicherzustellen, dass die Änderungen atomar auftreten Alle von ihnen sind sicher, sie verwenden nur verschiedene Strategien, um diese Sicherheit zu bieten. Vars sind wie globale Variablen in anderen Sprachen Die Wurzelbindung ist ein ursprünglicher Standardwert, der ist Geteilt von allen Threads Das Bindungskonstrukt wirkt so, als ob das Var geändert worden wäre, aber es wird automatisch auf seinen vorherigen Wert wiederhergestellt, wenn er den Bereich des Bindungskonstruktes beendet. Er stellt ein Var etwas mit dem Wert 5 fest. Deklarierende Funktionen stellen sie tatsächlich als Vars Du her Sollte vermeiden, def, und vor allem vermeiden, setzen bereits deklariert Bindungen mit def Nachfolgend rufen def etwas 6 ist kein fadensicherer Betrieb. Warum doesn t Clojure haben lokale Variablen ist eine oft aufgeworfene Frage Mutation lokal ist genauso schwer zu begründen wie Mutation global, unabhängig von Gleichzeitigkeit Siehe zum Beispiel eine typische Java für Schleife, die andere lokale Vars setzt und enthält Pausen Rückkehr Wenn es mehr Gedanken dauert Anfänglich, um Lösungen zu entwickeln, die nicht brauchen Variablen, bitte versuchen, die Anstrengung zu verbrauchen - es wird Ihnen viele Male über. Jedoch zu unterstützen direkte Übersetzung von Imperativ-Algorithmen, gibt es eine nützliche Makro mit-local-vars, die lokale Vars, die erklärt Kann mit var-set geändert werden und mit var-get oder für shorthand gelesen werden. Dies ist eine Version von Fakultät mit Variablen Wie Sie sehen können, ist es nicht so schön wie die früher beschriebenen Versionen und ist nur, um eine lokale Var-Bindung zu demonstrieren Funktion ist völlig sicher, um eine Multi-Thread-Umgebung aufzurufen, da die Variablen lokal sind. Allerdings können lokale Variablen nicht aus ihrem scope auslaufen. Ursachen Var null ist ungebunden Der Grund dafür ist, dass f eine neue Funktion zurückgibt, die 2 zu einem lokalen addiert Variable definiert in f Also die zurückgegebene Funktion versucht, eine lokale Variable von f zu behalten. Lokale Variablen unterliegen Änderungen, aber wenn die Änderung in einer Multi-Thread-Umgebung erfolgen sollte und diese Variable außerhalb ihres ursprünglichen Umfangs ausgelaufen war, Veränderung wäre nicht mehr lokal. Closure ist ein Begriff, der verwendet wird, wenn Symbole außerhalb ihrer Definition beibehalten werden. Dort haben wir zwei Funktionen geschaffen, die beide auf ein Ref-Geheimnis zugreifen. Wir haben sie in einem let erstellt, also ist das Geheimnis nicht mehr in unserem aktuellen Umfang sichtbar. Ursachen Nicht in der Lage, Symbol geheim in diesem Zusammenhang zu lösen. Jedoch die Funktionen selbst haben geheim gehalten und können es zu kommunizieren. Ergebnis in nichts. Clojure Moving Durchschnitt von Java zu Clojure. Clojure hat eine Arbeit mit Warteschlangen Ich weiß nicht, warum es doesn t ein Leser Makro, aber funktioniert gut und gibt Ihnen eine Clojure-Sammlung, die Sie mit Nachteile und Peek behandeln können. Sie können mit einem beginnen Leere Warteschlange mit oder legen Sie Ihre Artikel in den Konstruktor. Ich schrieb etwas Material darüber in Portugiesisch, wenn Sie Interesse haben. On 20 07 2014, um 08 48, schrieb Cecil Westerhof. Ich habe nur gefragt, was ist der beste Weg, dies zu übersetzen Zu Clojure. Im Moment hat Clojure keine Warteschlange Sollte ich einfach die Java-Anrufe benutzen, oder gibt es einen besseren Weg. - Cecil Westerhof - Du hast diese Nachricht erhalten, weil du die Google Groups Clojure Gruppe abonniert hast Diese Gruppe, E-Mail senden, um zu merken, dass Beiträge von neuen Mitgliedern moderiert werden - bitte seien Sie geduldig mit Ihrem ersten Beitrag Um sich von dieser Gruppe abzumelden, senden Sie eine E-Mail an clojure Für weitere Optionen besuchen Sie diese Gruppe bei --- Sie haben diese Nachricht erhalten, weil Sie sind Abonniert der Google Groups Clojure Gruppe Um sich von dieser Gruppe abzumelden und damit keine E-Mails zu erhalten, senden Sie eine E-Mail an Für weitere Optionen besuchen Sie .-- Sie haben diese Nachricht erhalten, weil Sie die Google Groups Clojure Gruppe abonniert haben , E-Mail senden, um zu merken, dass Beiträge von neuen Mitgliedern moderiert werden - bitte seien Sie geduldig mit Ihrem ersten Beitrag Um sich von dieser Gruppe abzumelden, senden Sie eine E-Mail an clojure Für weitere Optionen besuchen Sie diese Gruppe bei --- Sie haben diese Nachricht erhalten, weil Sie abonniert sind Die Google Groups-Clojure-Gruppe Um sich von dieser Gruppe abzumelden und zu stoppen, um E-Mails davon zu erhalten, senden Sie eine E-Mail an Für weitere Optionen, besuchen. Mike Fikes Es gibt tatsächlich eine Warteschlangen-Implementierung Hier ist eine Möglichkeit, es für Ihr Problem zu verwenden, Durchschnittliche queue n atom defn update-moving-average-queue old-queue next-value let current-total current-total old-queue next-value old-values ​​konj old-values ​​old-queue next-value if count old-values Length old-queue let current-total - aktuelle-total-first old-values ​​old-values. There tatsächlich ist eine Warteschlange Umsetzung Hier ist ein Weg, um es für Ihr Problem zu verwenden. Defn-make-moving-average-queue n atom current-total 0 0 old-values. Defen update-moving-average-queue old-queue next-value let current-total aktuell-total old-queue next-value old-values ​​konj old-werten old-queue next-value if count old-values ​​length old-queue let Aktuell-total-aktuell-insgesamt erste alt-werte alt-werte pop alt-werte ordnung alt-queue aktuell-total aktuell-total alt-werte alt-werte assoder old-queue aktuell-total aktuell-total old-values ​​old-values . Defn, bewegliche, durchschnittliche, alte, Warteschlange, next-value, lass, new-queue, Swap, old-queue, update-moving-average-queue, next-value, current-total, new-queue, count, old-values, new-queue. Def-Warteschlange-06 make-moving-average-queue 6. def eingänge-06 20 22 21 24 24 23 25 26 20 24 26 26 25 27 28 27 29 27 25 24. doseq input inputs-06 println moving-average queue-06 Eingang. Def-Warteschlange-10 make-moving-average-queue 10. def eingänge-10 20 22 24 25 23 26 28 26 29 27 28 30 27 29 28. doseq input inputs-10 println gleitende durchschnittliche queue-10 input Erhielt diese Nachricht, weil Sie die Google Groups-Clojure-Gruppe abonniert haben. Um diese Gruppe zu posten, senden Sie eine E-Mail an, um zu merken, dass Beiträge von neuen Mitgliedern moderiert werden - bitte seien Sie geduldig mit Ihrem ersten Beitrag Um sich von dieser Gruppe abzumelden, senden Sie eine E-Mail an clojure Für mehr Optionen, besuchen Sie diese Gruppe bei --- Sie erhielten diese Nachricht, weil Sie die Google Groups Clojure Gruppe abonniert haben Um sich von dieser Gruppe abzumelden und zu stoppen, E-Mails davon zu erhalten, senden Sie eine E-Mail an Für weitere Optionen besuchen Sie. Mike Fikes Hey Cecil, Neben der Verwendung von Peek statt der ersten, wie von Plinio angedeutet, verwendet die gleitende Durchschnitt-Funktion oben einige schlechte Namen, im Nachhinein, vor allem die alte Warteschlange Parameternamen I d vorschlagen, nennen sie Warteschlange, wie es sich auf ein Atom bezieht Auch die Namensgebung der Funktion Gleitender Durchschnitt - Du hast diese Nachricht erhalten, weil du die Google Groups-Clojure-Gruppe abonniert hast. Um diese Gruppe zu posten, schick eine E-Mail an E-Mail-geschützte Notizen, dass Beiträge von neuen Mitgliedern are. at 20. Juli 2014 bei 1 52 Uhr. Neben der Verwendung von Peek statt der ersten, wie von Plinio angedeutet, verwendet die gleitende Durchschnitt-Funktion oben einige schlechte Namen, im Nachhinein, vor allem der alte Warteschlangenparametername, den ich vorschlage, eine Warteschlange zu benennen, da sie sich auf einen bezieht Atom Sie könnten sogar in Erwägung ziehen, die Funktion gleitender Durchschnitt zu benennen. - Sie haben diese Nachricht erhalten, weil Sie die Google Groups-Clojure-Gruppe abonniert haben. Um diese Gruppe zu posten, senden Sie eine E-Mail an, um zu merken, dass Beiträge von neuen Mitgliedern moderiert werden - bitte sei geduldig mit Ihr erster Beitrag Um sich von dieser Gruppe abzumelden, schicken Sie eine E-Mail an clojure Für weitere Optionen besuchen Sie diese Gruppe unter --- Sie haben diese Nachricht erhalten, weil Sie die Google Groups-Clojure-Gruppe abonniert haben. Abmelden von dieser Gruppe und dem Starten von E-Mails, Senden Sie eine E-Mail an Für weitere Optionen, besuchen. Jony Hudson Wahrscheinlich nicht die Antwort, die Sie suchen, aber die exponentiell gewichteten gleitenden Durchschnitt doesn t erfordern einen anderen Staat als der aktuelle Wert defn ewma alpha fn avg neu - 1 alpha avg alpha neu Jony - Du hast diese Nachricht erhalten, weil du die Google Groups-Clojure-Gruppe abonniert hast. Um diese Gruppe zu posten, schick eine E-Mail an E-Mail-geschützte Notizen, dass Beiträge von neuen Mitgliedern moderiert werden - bitte sei geduldig mit deinem ersten Beitrag Um sich von dieser Gruppe abzumelden, Send. On Sonntag, 20. Juli 2014 12 48 19 UTC 1, Cecil Westerhof schrieb. or gibt es einen besseren Weg. Wahrscheinlich nicht die Antwort, die du suchst, aber der exponentiell gewichtete gleitende Durchschnitt benötigt keinen anderen Staat als den Strom Wert. Defn ewma alpha fn avg neu - 1 alpha avg alpha neu .-- Du hast diese Nachricht erhalten, weil du die Google Groups Clojure Gruppe abonniert hast. Um diese Gruppe zu posten, schick die E-Mail an, um zu merken, dass Beiträge von neuen Mitgliedern moderiert sind - bitte sei geduldig with your first post To unsubscribe from this group, send email to clojure For more options, visit this group at --- You received this message because you are subscribed to the Google Groups Clojure group To unsubscribe from this group and stop receiving emails from it , send an email to For more options, visit.


No comments:

Post a Comment