Gibt es Nachteile oder Probleme mit Haskell?

47

Ich freue mich darauf, in Haskell für mein nächstes (relativ einfaches) persönliches Projekt einzutauchen. Die Gründe, warum ich Haskell angreife, sind:

  1. Bringe meinen Kopf in eine rein funktionale Sprache
  2. Geschwindigkeit. Obwohl ich mir sicher bin, dass dies argumentiert werden kann, habe ich ein Profil erstellt, bei dem ich Haskell in der Nähe von C ++ gesehen habe (und das ziemlich viel schneller zu sein scheint als Erlang).
  3. Geschwindigkeit. Der Warp-Webserver scheint im Vergleich zu fast allem anderen schnell verrückt zu sein .

Vor diesem Hintergrund suche ich nach den Nachteilen oder Problemen, die mit Haskell einhergehen. Das Web hat eine enorme Menge an Informationen darüber, warum Haskell eine gute Sache ist, aber ich habe nicht viele Themen über seine hässliche Seite gefunden (abgesehen von den Griffen über seine Syntax, die mir überhaupt nichts ausmachen).

Ein Beispiel für das, wonach ich suche, könnte Pythons GIL sein. Etwas, das seinen Kopf nicht aufrichtete, bis ich wirklich anfing, Parallelität in einer CPython-Umgebung zu verwenden.

Demian Brecht
quelle
4
Dies wurde auf stackoverflow gefunden: stackoverflow.com/questions/1695076/pros-and-cons-of-haskell
FrustratedWithFormsDesigner
26
Ich habe gehört, dass weniger Programmierer sich mit Fragen des Brain Meltings befasst haben. Es ist eine sehr teure Bedingung zu behandeln.
ChaosPandion
1
@FrustratedWithFormsDesigner: Danke für den Link. Es gibt jedoch immer noch keinen Hinweis auf technische Nachteile von Haskell. Könnte es sein, dass es keine gibt? ;)
Demian Brecht
6
@ChaosPandion: Ich habe dasselbe gehört. Aber wenn Sie Ihr Gehirn nicht zum Schmelzen bringen, versuchen Sie es tatsächlich ? ;) Außerdem würde ich mich selbst nicht als weniger
Demian Brecht,
3
@ChaosPandion: Und die meisten Gesundheitspläne decken das nicht ab. :(
FrustratedWithFormsDesigner

Antworten:

48

Ein paar Nachteile, die ich mir vorstellen kann:

  • Aufgrund der Natur der Sprache und ihrer festen Wurzeln in der akademischen Welt ist die Community sehr mathematisch eingestellt. Wenn Sie eine pragmatische Person sind, kann dies manchmal überwältigend sein, und wenn Sie den Jargon nicht sprechen, haben Sie es schwerer als mit vielen anderen Sprachen.
  • Obwohl es eine unglaubliche Fülle von Bibliotheken gibt, ist die Dokumentation oft knapp.
  • Es gibt nur wenige und schwer zu findende Tutorials für Anfänger, daher ist die anfängliche Lernkurve ziemlich steil.
  • Einige Sprachmerkmale sind unnötig umständlich. Ein prominentes Beispiel dafür ist, dass die Datensatzsyntax keinen Namensbereich einführt, sodass es nicht möglich ist, denselben Datensatzfeldnamen in zwei verschiedenen Typen innerhalb desselben Modulnamensraums zu haben.
  • Haskell verwendet standardmäßig eine verzögerte Auswertung. Dies ist zwar oft eine großartige Sache, kann Sie aber manchmal auf unangenehme Weise beißen. Die naive Verwendung von Lazy Evaluation in nicht-trivialen Situationen kann zu unnötigen Leistungsengpässen führen, und es ist nicht ganz einfach zu verstehen, was unter der Haube vor sich geht.
  • Eine langsame Auswertung (insbesondere in Verbindung mit der Reinheit und einem aggressiv optimierenden Compiler) bedeutet auch, dass Sie die Ausführungsreihenfolge nicht ohne Weiteres beurteilen können. Tatsächlich wissen Sie nicht einmal, ob ein bestimmter Code in einer bestimmten Situation tatsächlich ausgewertet wird. Infolgedessen erfordert das Debuggen von Haskell-Code eine andere Denkweise, schon allein deshalb, weil das Durchgehen Ihres Codes weniger nützlich und weniger aussagekräftig ist.
  • Aufgrund der Reinheit von Haskell können Sie keine Nebenwirkungen verwenden, um Dinge wie E / A auszuführen. Sie müssen eine Monaden- und Missbrauchs-Lazy-Evaluierung verwenden, um Interaktivität zu erreichen, und Sie müssen den monadischen Kontext überall hin ziehen, wo Sie I / O ausführen möchten. (Dies ist in vielerlei Hinsicht eine gute Funktion, macht aber manchmal eine pragmatische Codierung unmöglich.)
tdammers
quelle
16
Es gibt tatsächlich einige wirklich gute Einführungsbücher, die jetzt kostenlos online verfügbar sind. Learn You a Haskell for Great Good ist eines der besten Programmierbücher für Anfänger, die ich je gelesen habe, und Real World Haskell ist eine großartige Zwischenressource.
Tikhon Jelvis
1
@TikhonJelvis: Das sind in der Tat die einzigen zwei Kandidaten, die ich für nützlich befunden habe. "Learn You A Haskell" hat mich mehr als alles andere verwirrt, "Real World Haskell" hat für mich gearbeitet, setzt aber ein bisschen Programmierkenntnisse voraus. Es gibt auch "Sanfte Einführung in Haskell", aber es ist alles andere als sanft, besonders wenn Sie keinen Hintergrund in Mathe haben.
Tdammers
Ich benutze "Gentle Introduction to Haskell" und "Real World Haskell". Die Kombination der beiden gab mir viele nützliche Informationen. Ich bin auf einem Niveau, auf dem ich für ein nicht triviales Projekt bereit bin, aber leider habe ich nicht viel Zeit dafür.
Giorgio
9
"Wenn Sie eine pragmatische Person sind ...": Manchmal kann die Verwendung einer mathematisch orientierten Sprache eine sehr pragmatische Entscheidung sein, wenn Sie später nicht viele Fehler beheben müssen. Natürlich sollten Sie immer ein Gleichgewicht finden zwischen der Zeitersparnis mit einem Tool und der zusätzlichen Zeit, die Sie benötigen, um den Umgang mit dem Tool zu erlernen.
Giorgio,
Monaden würden (und tun dies in anderen Sprachen) genauso in einer strengen Sprache arbeiten. Sie "missbrauchen" keine faulen Auswertungen, um Interaktivität zu erreichen. Es ist trivial, ein striktes interaktives Programm in Haskell zu schreiben.
Semikolon
19

Die meisten Nachteile von Haskell (wie auch die meisten Nachteile von Haskell) beruhen auf den beiden Hauptmerkmalen: Es ist faul und rein funktional.

Faul zu sein macht es schwieriger, über die Leistung nachzudenken. Besonders für Leute, die nicht an Faulheit gewöhnt sind, aber selbst für erfahrene Haskeller kann es schwierig sein zu sehen, wie Faulheit in bestimmten Fällen die Leistung beeinflusst.

Faulheit bedeutet auch, dass es schwieriger ist, genaue Benchmarks zu erstellen, ohne Bibliotheken wie Criterion zu verwenden.

Rein funktional zu sein bedeutet, dass Sie immer dann, wenn Sie veränderbare Datenstrukturen verwenden müssen (in Fällen, in denen es nicht möglich ist, die gewünschte Leistung ohne diese zu erzielen - obwohl dies dank des Optimierers von GHC nicht so oft vorkommt, wie Sie vielleicht denken) stecken in der IO (oder ST) Monade, was den Code umständlicher macht.

Da Sie Geschwindigkeit als eines Ihrer Ziele genannt haben, sollte ich darauf hinweisen, dass es zwischen handoptimiertem Haskell-Code und Haskell-Code, der geschrieben wurde, oft enorme Leistungsunterschiede gibt, ohne die Leistung zu berücksichtigen (mehr als in anderen Sprachen). Und handoptimierter Haskell-Code ist oft ziemlich hässlich (obwohl ich annehme, dass dies auch in den meisten anderen Sprachen zutrifft).

sepp2k
quelle
1
Rein funktional ist eigentlich ein Verkaufsmerkmal, kein Nachteil. Eine Sprache, die "faul" ist, ergibt keinen Sinn, faul gegen streng ist eine Frage der Typen, und sowohl faule als auch strenge Typen haben ihre Verwendungszwecke. (Haskell ist also genauso verkrüppelt, weil es keine strengen Typen gibt, wie die meisten Sprachen, weil es keine faulen Typen gibt.) Die Hauptnachteile von Haskell sind das beschissene Modulsystem (Module sind nicht erstklassig) und die Tatsache, dass Typklassen tatsächlich die Modularität aufheben (die Die Regel "eine Instanz pro Typ" zwingt den Compiler, eine globale Liste von Typklasseninstanzen zu führen.
Pyon
21
"Und handoptimierter Haskell-Code ist oft ziemlich hässlich (obwohl ich denke, dass dies auch in den meisten anderen Sprachen zutrifft)." Diese. Wenn die Leute die Eleganz von Haskell zeigen wollen, veröffentlichen sie kurzen und süßen Code, der bei einer produktionsähnlichen Datenmenge leider zu einer ziemlich schlechten Leistung führt. Wenn Leute zeigen wollen, dass "Haskell so schnell wie C ++ ist", veröffentlichen sie verschlungenen und schwer lesbaren Code, der immer noch langsamer ist als eine viel besser lesbare Version in C.
quant_dev
12

Ich bin kein Haskell-Experte: Ich habe die Grundlagen gelernt, aber leider hatte ich keine Gelegenheit, ein ernstes Projekt in Haskell zu machen (ich würde es jedoch mögen, weil ich diese Sprache sehr mag).

Nach dem, was ich weiß, und nach einer Diskussion mit jemandem, der auf einem Gebiet arbeitet, das der funktionalen Programmierung sehr nahe steht, ist Haskell möglicherweise nicht die beste Lösung, wenn Sie Algorithmen für Diagramme implementieren möchten, bei denen Sie z Viele lokale Änderungen in der Diagrammstruktur.

Da ein Diagramm im Allgemeinen keine rekursive Struktur hat, ist es meines Erachtens der beste Ansatz, eine Kopie des Diagramms unter Verwendung von Strukturen und Zeigern zwischen ihnen zu erstellen (wie Sie es z. B. in C ++ tun können) und diese Kopie durch Ändern von Zeigern zu manipulieren. Erstellen oder Zerstören von Knoten und so weiter.

Ich frage mich, wie solche Datenstrukturen und Operationen in Haskell richtig gehandhabt werden können, da es meines Wissens in Haskell nicht möglich ist, die obige Darstellung / Vorgehensweise zu verwenden. In diesem Artikel werden einige Probleme mit Diagrammalgorithmen in Haskell kurz erläutert

BEARBEITEN

Ich habe kürzlich mit einem Experten für funktionale Programmierung gesprochen und er hat bestätigt, dass es in Haskell sehr schwierig sein kann, bestimmte Grafikalgorithmen effizient zu implementieren: Das Bewegen von Zeigern wie in C oder C ++ kann viel schneller sein.

Giorgio
quelle
Interessante Hinweise (und Links) zur Graphmanipulation / -durchquerung in einer reinen Funktionswelt. Hatte das nicht bedacht.
Demian Brecht
7
Rein funktionale Graph-Algorithmen sind ein interessantes Thema. Die idiomatische Lösung besteht darin, die imperative Repräsentation zu emulieren, indem Zeiger durch rein funktionale Wörterbücher ersetzt werden, z. B. indem ein gegebener Scheitelpunkt der Menge von Scheitelpunkten zugeordnet wird, zu denen er Kanten hat. Wenn jedoch kein schwaches Wörterbuch verwendet wird, führt dies zu einem Speicherverlust, da nicht erreichbare Untergraphen nicht erfasst werden können und kein rein funktionales schwaches Wörterbuch bekannt ist. Letztendlich ist eine hochmoderne, rein funktionale Lösung weitaus komplizierter und weitaus weniger effizient!
Jon Harrop
1
Auf der anderen Seite können Graph-Algorithmen notorisch schwierig zu debuggen sein und eine beständige Datenstruktur kann dieses Problem lindern ...
Jon Harrop
Ich habe mich gefragt, ob es möglich ist, einen Graph-Datentyp zu entwickeln (nach der Idee von ByteString: effiziente interne Darstellung plus Konvertierungs- / Zugriffsfunktionen). Mit Monaden sollte es möglich sein, solche Graphen veränderbar zu machen. Dies würde sich natürlich mit dem Problem der Darstellung von Graphen befassen, nicht jedoch mit der Implementierung von Graphenalgorithmen.
Giorgio
DAGs sind eine Sache. Für alles andere können Sie Faulheit ausnutzen und "den Knoten knüpfen".
Danielm
4

Die Kehrseite von Haskell ist, dass es anders ist. Es ist ein größerer Schritt weg von Sprachen, die häufiger unterrichtet oder über die gesprochen wird, und es wird eine größere Lernkurve geben. Es ist auch weniger beliebt in einer Sprache, die die Verfügbarkeit von Hilfe einschränkt, wenn Sie nicht weiterkommen. Dies sind jedoch keine großen Nachteile.

Ein möglicher Nachteil ist, dass es sich um eine funktionale Sprache handelt, die für bestimmte Problembereiche weniger nützlich ist. Dies gilt jedoch auch für objektorientierte Sprachen. Im Allgemeinen haben Sprachen keine echten Negative jenseits der Lernkurven, zumindest für die relativ populären Sprachen. Solange eine Sprache vollständig ist, ist sie theoretisch zu allem fähig.

Ryathal
quelle
3
Die Vollständigkeit ist ein roter Hering. Berechnungstheorie! = Praktische Programmierung.
1
@delnan das ist, warum ich theoretisch sagte
Ryathal
2
Was sind diese "Problemdomänen", für die Haskell angeblich weniger nützlich ist?
Andres F.
3
Die Community ist zwar kleiner , aber tatsächlich überproportional aktiv. Ich denke, der #haskell-Kanal auf freenode steht nur hinter der Popularität von #python in den Sprachkanälen, und die Beantwortung von Fragen zu Haskell auf SO ist überraschend wettbewerbsfähig :)
Tikhon Jelvis
@AndresF. - Ich würde nicht so weit gehen, "weniger nützlich" zu sagen, aber hier sind einige Bereiche, in denen Haskell definitiv noch in den Kinderschuhen steckt: 1) Schwere DP - Ich habe einen einfachen Rucksack-Algorithmus programmiert und war buchstäblich schockiert darüber, wie Langsam war es. Das verwendete Boxed Arrays, also erwartete ich etwas Overhead, aber es war viel schlimmer als ich erwartet hatte. 2) große, nicht triviale Spiele - AFRP steckt noch in den Kinderschuhen, daher gibt es keine besonders guten Frameworks, und die Leistung ist immer noch zu schwer vorherzusagen. Es wird lange dauern, bis wir die Haskell-Version von Doom sehen. (Frag zählt nicht - es hat keine KI.)
RTPerson
0

Vor diesem Hintergrund suche ich nach den Nachteilen oder Problemen, die mit Haskell einhergehen

Die "Probleme mit Haskell" treten in der Regel in bestimmten Domänen auf. Haskell ist eine wunderbare Sprache für die Anwendungsprogrammierung, die viel angenehmer zu schreiben ist als alles andere. Die Probleme treten in der Regel auf, wenn Sie versuchen, etwas zu tun, für das es keine gute Unterstützung gibt, beispielsweise:

  • Cross-Kompilierung. GHC kann als Cross-Compiler erstellt werden, der Prozess ist jedoch sehr aufwändig.
  • Embedded-Anwendungen. Haskell verfügt über eine Speicherverwaltung über einen Garbage Collector, so dass dieser nicht allzu überraschend ist.
  • Geschwindigkeit. Haskell ist nicht so schnell wie Rust, aber in den meisten Fällen wird es ziemlich gut konkurrieren. Es hängt stark von der Anwendungsdomäne ab - reine Berechnungen werden gut optimiert, aber so etwas wie "Lesen einer Datei in einen Puffer und Zählen der Zeilenanzahl" ist in Haskell schwerer auszudrücken.

quelle