Ich versuche, einige einfache automatische physikalische Systeme (wie Pendel, Roboterarme usw.) In Haskell zu visualisieren. Oft können diese Systeme durch Gleichungen wie beschrieben werden
df/dt = c*f(t) + u(t)
wo u(t)
repräsentiert eine Art "intelligente Steuerung". Diese Systeme scheinen sehr gut in das Paradigma der funktionalen reaktiven Programmierung zu passen.
Also habe ich das Buch „The Haskell School of Expression“ von Paul Hudak packte und festgestellt , dass die domänenspezifische Sprache „FAL“ (für Functional - Animation Language) präsentierte dort recht tatsächlich funktioniert pleasently für meine einfachen Spielzeug - Systeme (auch wenn einige Funktionen, vor allem integrate
, schien ein bisschen zu faul für eine effiziente Nutzung zu sein, aber leicht zu reparieren).
Meine Frage ist, was ist die ausgereiftere, aktuellere, gepflegte, leistungsoptimierte Alternative für fortgeschrittenere oder sogar praktische Anwendungen heute?
Diese Wiki-Seite listet verschiedene Optionen für Haskell auf, aber mir sind die folgenden Punkte nicht klar:
Der Status von "reaktiv", dem Projekt von Conal Eliott, der (wie ich es verstehe) einer der Erfinder dieses Programmierparadigmas ist, sieht etwas abgestanden aus. Ich liebe seinen Code, aber vielleicht sollte ich andere aktuellere Alternativen ausprobieren? Was ist der Hauptunterschied zwischen ihnen in Bezug auf Syntax / Leistung / Laufzeitstabilität?
Um aus einer Umfrage im Jahr 2011 zu zitieren , Abschnitt 6: " ... FRP-Implementierungen sind immer noch nicht effizient genug oder vorhersehbar genug, um in Domänen, in denen Latenzgarantien erforderlich sind, effektiv eingesetzt zu werden ... ". Obwohl die Umfrage einige interessante mögliche Optimierungen vorschlägt, da FRP seit mehr als 15 Jahren besteht, habe ich den Eindruck, dass dieses Leistungsproblem zumindest innerhalb weniger Jahre sehr oder sogar von Natur aus schwierig zu lösen sein könnte . Ist das wahr?
Der gleiche Autor der Umfrage spricht in seinem Blog über "Zeitlecks" . Ist das Problem nur bei FRP oder etwas, das wir normalerweise haben, wenn wir in einer reinen, nicht strengen Sprache programmieren? Haben Sie es jemals zu schwierig gefunden, ein FRP-basiertes System im Laufe der Zeit zu stabilisieren, wenn nicht leistungsfähig genug?
Ist das noch ein Forschungsprojekt? Verwenden die Leute wie Anlageningenieure, Robotikingenieure, Finanzingenieure usw. sie tatsächlich (in welcher Sprache auch immer, die ihren Bedürfnissen entspricht)?
Obwohl ich persönlich eine Haskell-Implementierung bevorzuge, bin ich offen für andere Vorschläge. Zum Beispiel würde es besonders Spaß machen, eine Erlang-Implementierung zu haben - es wäre dann sehr einfach, einen intelligenten, adaptiven, selbstlernenden Serverprozess zu haben!
Obwohl es bereits einige gute Antworten gibt, werde ich versuchen, Ihre spezifischen Fragen zu beantworten.
reaktiv ist aufgrund von Zeitleckproblemen nicht für ernsthafte Projekte verwendbar. (siehe # 3). Die aktuelle Bibliothek mit dem ähnlichsten Design ist Reactive-Banana, die mit Reactive als Inspiration und im Gespräch mit Conal Elliott entwickelt wurde.
Obwohl Haskell selbst für harte Echtzeitanwendungen ungeeignet ist, ist es in einigen Fällen möglich, Haskell für weiche Echtzeitanwendungen zu verwenden. Ich bin mit der aktuellen Forschung nicht vertraut, aber ich glaube nicht, dass dies ein unüberwindbares Problem ist. Ich vermute, dass entweder Systeme wie Yampa oder Codegenerierungssysteme wie Atom möglicherweise der beste Ansatz sind, um dies zu lösen.
Ein "Zeitleck" ist ein spezifisches Problem bei schaltbarem FRP. Das Leck tritt auf, wenn ein System alte Objekte nicht freigeben kann, weil es sie möglicherweise benötigt, wenn irgendwann in der Zukunft ein Wechsel stattfinden sollte. Zusätzlich zu einem Speicherverlust (der sehr schwerwiegend sein kann) besteht eine weitere Konsequenz darin, dass das System beim Umschalten eine Pause einlegen muss, während die Kette alter Objekte durchlaufen wird, um den aktuellen Status zu generieren.
Nicht umschaltbare frp-Bibliotheken wie Yampa und ältere Versionen von reaktiven Bananen leiden nicht unter Zeitlecks. Umschaltbare frp-Bibliotheken verwenden im Allgemeinen eines von zwei Schemata: Entweder haben sie eine spezielle "Erstellungsmonade", in der FRP-Werte erstellt werden, oder sie verwenden einen Parameter vom Typ "Alterung", um die Kontexte zu begrenzen, in denen Umschaltungen auftreten können. elerea (und möglicherweise netwire?) verwenden das erstere, während neuere reaktive Bananen und Grapefruits das letztere verwenden.
Mit "schaltbar frp" meine ich eine, die Conals Funktion
switcher :: Behavior a -> Event (Behavior a) -> Behavior a
oder identische Semantik implementiert . Dies bedeutet, dass sich die Form des Netzwerks während des Betriebs dynamisch ändern kann.Dies widerspricht nicht wirklich der Aussage von @ ertes über monadische Schnittstellen: Es stellt sich heraus, dass die Bereitstellung einer
Monad
Instanz für eineEvent
Zeitlecks ermöglicht, und mit einem der oben genannten Ansätze ist es nicht mehr möglich, die entsprechenden Monad-Instanzen zu definieren.Obwohl noch viel Arbeit mit FRP zu erledigen ist, denke ich, dass einige der neueren Plattformen (Reactive-Banana, Elerea, Netwire) stabil und ausgereift genug sind, um daraus zuverlässigen Code zu erstellen. Möglicherweise müssen Sie jedoch viel Zeit damit verbringen, die Vor- und Nachteile zu erlernen, um zu verstehen, wie Sie eine gute Leistung erzielen.
quelle
Ich werde ein paar Elemente im Mono- und .Net-Bereich und eines aus dem Haskell-Bereich auflisten, die ich vor nicht allzu langer Zeit gefunden habe. Ich werde mit Haskell beginnen.
Ulme - Link
Seine Beschreibung gemäß seiner Website:
Es hat eine eigene Variante von FRP . Wenn man mit seinen Beispielen spielt, scheint es ziemlich ausgereift zu sein.
Reaktive Erweiterungen - Link
Beschreibung von seiner Titelseite:
Reactive Extensions stammt von MSFT und implementiert viele hervorragende Operatoren, die die Behandlung von Ereignissen vereinfachen. Es war erst vor ein paar Tagen Open Source . Es ist sehr ausgereift und wird in der Produktion verwendet. Meiner Meinung nach wäre es eine schönere API für die Windows 8-APIs gewesen, als die TPL-Bibliothek bietet. weil Observables sowohl heiß als auch kalt sein und erneut versucht / zusammengeführt werden können usw., während Aufgaben immer heiße oder durchgeführte Berechnungen darstellen, die entweder ausgeführt, fehlerhaft oder abgeschlossen sind.
Ich habe serverseitigen Code mit Rx für Asynchronität geschrieben, aber ich muss zugeben, dass das funktionale Schreiben in C # etwas ärgerlich sein kann. F # hat ein paar Wrapper, aber es war schwierig, die API-Entwicklung zu verfolgen, da die Gruppe relativ geschlossen ist und nicht wie andere Projekte von MSFT beworben wird.
Das Open Sourcing wurde mit dem Open Sourcing des IL-to-JS-Compilers geliefert, sodass es wahrscheinlich gut mit JavaScript oder Elm funktionieren könnte.
Sie könnten F # / C # / JS / Haskell wahrscheinlich sehr gut mit einem Nachrichtenbroker wie RabbitMQ und SocksJS zusammenbinden.
Bling UI Toolkit - Link
Beschreibung von seiner Titelseite:
Ein kostenloser LTU-Artikel .
Ich habe dies getestet, aber nicht für ein Kundenprojekt damit gearbeitet. Es sieht fantastisch aus und hat eine nette Überladung des C # -Operators, die die Bindungen zwischen den Werten bildet. Es verwendet Abhängigkeitseigenschaften in WPF / SL / (WinRT) als Ereignisquellen. Die 3D-Animationen funktionieren gut mit vernünftiger Hardware. Ich würde dies verwenden, wenn ich in einem Projekt landen würde, das Visualisierungen benötigt. wahrscheinlich auf Windows 8 portieren.
ReactiveUI - Link
Paul Betts, zuvor bei MSFT, jetzt bei Github, hat diesen Rahmen geschrieben. Ich habe ziemlich ausgiebig damit gearbeitet und mag das Modell. Es ist entkoppelter als Blink (von Natur aus von der Verwendung von Rx und seinen Abstraktionen), was es einfacher macht, Code mit ihm zu testen. Darin ist der Github Git Client für Windows geschrieben.
Bemerkungen
Das reaktive Modell ist für die meisten leistungsintensiven Anwendungen leistungsfähig genug. Wenn Sie an harte Echtzeit denken, würde ich wetten, dass die meisten GC-Sprachen Probleme haben. Rx, ReactiveUI erstellen eine gewisse Menge kleiner Objekte, die GCed werden müssen, da auf diese Weise Abonnements erstellt / entsorgt werden und Zwischenwerte in der reaktiven "Monade" von Rückrufen weiterentwickelt werden. Im Allgemeinen bevorzuge ich in .Net die reaktive Programmierung gegenüber der aufgabenbasierten Programmierung, da Rückrufe statisch sind (zur Kompilierungszeit bekannt, keine Zuordnung), während Aufgaben dynamisch zugewiesen werden (nicht bekannt, alle Aufrufe benötigen eine Instanz, Müll erstellt) - und Lambdas kompilieren vom Compiler generierte Klassen.
Offensichtlich werden C # und F # streng ausgewertet, so dass Zeitlecks hier kein Problem darstellen. Gleiches gilt für JS. Es kann jedoch ein Problem mit wiedergabefähigen oder zwischengespeicherten Observablen sein.
quelle
u(t)
und die Simulationen für sauber zu entkoppelnf(t)
. Ist das bei F # -Implementierungen der Fall?