Für das gesamte vergangene Jahr habe ich Scala- Code geschrieben (mit Java-Hintergrund). Es hat mir sehr gut gefallen, wie Sie einfacheren und saubereren Code mit Vals, Case-Klassen, Map / Filter / Lambda-Funktionen, Implicits und der Typinferenz erstellen können. Ich habe es hauptsächlich für eine Akka- basierte Anwendung verwendet.
Dieses Jahr bin ich in einem Scala-Projekt mit einem neuen Team, das funktionale Programmierung wirklich mag. Sie verwenden häufig Scalaz , und der Code ist überall mit Anwendern, Kontextgrenzen, Lese- / Schreib- / Statusmonaden gefüllt, selbst die Hauptmethode ist in eine E / A-Monade "eingepackt". Ihre Argumentation ist, dass dies den Compiler dazu bringt, "für uns zu arbeiten", zu behaupten, dass der Code korrekt ist und jede Funktion frei von Nebenwirkungen ist.
Trotzdem steht aus meiner Sicht all diese Syntax der Geschäftslogik im Weg. Ein Typ von "MyBusinessObject" ist beispielsweise in Ordnung, ebenso wie Typen wie "List [MyBusinessObject]", "Option [MyBusinessObject]" oder sogar "Future [MyBusinessObject]". Sie alle haben eine klare Bedeutung und einen klaren Zweck. Auf der anderen Seite Code wie:
def method[M[_]: Applicative] = {
case (a, b) => (ca[M](a) |@| cb[M](b)) {
case t @ (ra, rb) =>
if (ra.result && rb.result) t.right
else t.left
}
}
Fügt es dem Programm Komplexität hinzu, oder bin ich nur an diese Art der Programmierung nicht gewöhnt?
quelle
>>=
und<$>
, die bis auf Sie nichts bedeuten wissen was sie tun. Nachdem sie gelernt haben, was sie bedeuten, lesen sie mir jetzt ganz natürlich und schnell vor. Keine wirkliche Antwort, nur meine objektive Erfahrung mit solchen Dingen. Ich benutze auch Scala, habe aber keine Erfahrung mit der Scalaz-Bibliothek.for(i=0; i<7; ++i) { trivialOperation(i); }
mit einer umständlichentrivialOperationCount
Variablen schreiben , oder?). In funktionalen Programmiersprachen mit Pattern Matching werden manchmal weitere Variablen eingeführt schreibe einfach Accessor Methodenaufrufe in OO aus. Das Ergebnis ist im Allgemeinen prägnanter. Vielleicht ein bisschen weniger selbsterklärend, aber das Nachschlagen der Datendeklaration macht es normalerweise schnell klar. Statische Eingabe hilft sehr, es ist nicht wie in APL.Antworten:
Dies hat nichts mit funktionaler Programmierung zu tun - Sie können diese Art von Situation im Kontext jeder anderen Programmiersprache finden - Entwickler, die die fortgeschrittenen Konstrukte "ihrer" Sprache so sehr lieben, dass sie jeglichen gesunden Menschenverstand in Bezug auf Lesbarkeit und einfache Dinge ignorieren. Ich habe eine solche Situation in C, C ++, Perl, Java, C #, Basic und anderen nicht funktionierenden Sprachen erlebt. Es ist nicht die funktionale Programmierung, die dem Code Komplexität verleiht - das tun Programmierer.
Verstehen Sie mich nicht falsch, ich empfehle nicht, erweiterte Sprachfunktionen zu vermeiden - aber es ist wichtig, das richtige Gleichgewicht im gegebenen Kontext zu finden. Wenn Sie eine generische Bibliothek für die Verwendung von mehr als 100.000 Entwicklern auf der ganzen Welt schreiben, müssen Sie unterschiedliche Maßnahmen anwenden, als würden Sie einen individuellen Berichtsgenerator nur für Ihr lokales Büro schreiben.
quelle
Ich würde sagen, dass Sie nicht daran gewöhnt sind, wie sie codieren, zumindest ein Teil des Bildes ist. Ich bin in einer ähnlichen Situation wie Sie (ich komme von C # nach F # und arbeite mit Leuten mit Haskell-Hintergrund), und obwohl ich das für eine interessante Erfahrung halte, habe ich Momente, in denen ich meinen Kopf gegen die Wand stoße und a entwirre besonders gewundene punktfreie Funktionskomposition, nur um einen Überblick zu bekommen, was dort vor sich geht. Es ist eine kulturelle Sache.
Ob dieser spezielle Code dem Programm Komplexität verleiht, weiß ich nicht. Einig, dass ein generischer Code selbst komplex sein kann. Aber es ist ein Dienstprogramm, kein Teil der Geschäftslogik. Wenn Sie wissen möchten, ob die Codebasis dadurch komplexer oder einfacher wird, müssen Sie sich vorstellen, wie sie ohne diesen Code aussehen müsste. Bei solchen generischen Konstrukten ist es häufig der Fall, dass sie selbst komplex sind, aber es ist eine Komplexität, die Sie auf einen einzelnen Bildschirm anpassen können. Gleichzeitig vereinfachen sie die gesamte Codebasis ein gutes Stück. Dies ist insbesondere bei Monaden der Fall.
Andererseits kann es sich auch um "Kunst um der Kunst willen" handeln, wie @Doc Brown vorschlägt. Kann es auch nicht ausschließen.
quelle
Ich würde argumentieren, dass funktionale Programmierung im Allgemeinen die Komplexität reduziert, indem sie den veränderlichen Zustand eliminiert, wodurch die Anzahl der Fälle reduziert wird, die berücksichtigt werden müssen, wenn versucht wird, die Funktionsweise eines Codeabschnitts zu verstehen.
Die funktionale Programmierung ermöglicht jedoch höhere Abstraktionsgrade, und obwohl hoch abstrakter Code äußerst nützlich sein kann, kann er auch schwer zu verstehen sein, da er per definitionem von dem Kontext getrennt ist, den Sie normalerweise als Leitfaden für Ihr Verständnis verwenden würden. Ihr Kommentar "Sie alle haben eine klare Bedeutung und einen klaren Zweck" zu Geschäftsobjekten ist zweifellos wahr, spiegelt jedoch die Tatsache wider, dass diese Logik sehr spezifisch für ein Bedürfnis und einen Kontext ist, die Sie bereits verstehen. Die Existenz eines Konstrukts wie Monad ermöglicht es Ihnen, mit geringem Aufwand etwas sehr Nützliches zu erstellen, aber das Web ist übersät mit Seiten, die versuchen zu erklären, was eine Monad ist. Das ist Abstraktion für dich.
Außerdem wurde Scalaz von Leuten geschrieben, die schon lange FP gegessen und geatmet hatten. Sie wollten die Funktionalität von Haskell für Scala verfügbar machen. Dabei machten sie keinen Versuch, pädagogisch zu sein. Scalaz bedient sich eines Wortschatzes und Stils, der den Autoren klar und direkt erscheint, den Uneingeweihten jedoch fremd ist. Methoden, die für den Rest von uns rätselhaft sind, schienen den Autoren angesichts ihres Haskell-Hintergrunds so offensichtlich, dass sie nicht einmal einen Kommentar rechtfertigten.
Darüber hinaus weist Scala als funktionale Programmiersprache einige Mängel auf (teilweise, weil die JVM Mängel aufweist), die die Scalaz-Autoren in einigen Fällen gezwungen haben, hässlicheren Code zu schreiben. Zum Beispiel erzwingt das Fehlen einer generellen Tail-Call-Eliminierung die Verwendung von Trampolinen in einigen Codes, und das Fehlen eines "freundlichen Systems" kann Typensignaturen erschweren.
Und schließlich nutzt Scalaz sich selbst sehr gut aus. Das könnte man sich als Zeichen seiner Macht vorstellen, aber für den Uneingeweihten kann es die Quelle zu einem Rätsel machen - jeder zufällige Code, den Sie ansehen, wird wahrscheinlich etwas anderes gebrauchen, das Ihnen fremd vorkommt.
Halte durch. Und das könnte helfen.
quelle
Fügt es dem Programm Komplexität hinzu, oder ist es nur so, dass Sie nicht an diese Art der Programmierung gewöhnt sind?
Warum denken Sie, sind diese Möglichkeiten nicht dasselbe?
Gut geschriebener Code kann von Personen gelesen werden, die mit der jeweiligen Programmiersprache nicht vertraut sind. Einige Sprachen (BASIC, Pascal usw.) können von Schulkindern gelesen und verstanden werden, die noch nie zuvor eine Programmiersprache gesehen haben.
Wenn jemand, der Erfahrung mit anderen Sprachen und Erfahrung mit Scala hat (und von dem ich annehme, dass er mindestens eine Woche mit Scalaz gearbeitet hat und Kollegen hat, die die schwierigeren Dinge erklären), immer noch verwirrt ist; dann ist das ein Beweis dafür, dass es die Komplexität erhöht hat.
quelle
"Well written code can be read by people who aren't familiar with the specific programming language."
x[⍋x←6?40]
. Was glaubst du, was es tut? Ich hätte es sicher nicht gewusst…