web-dev-qa-db-fra.com

Y a-t-il des inconvénients ou des problèmes avec Haskell?

J'envisage de plonger dans Haskell pour mon prochain projet personnel (relativement trivial). Les raisons pour lesquelles je m'attaque à Haskell sont:

  1. Mets ma tête dans un langage purement fonctionnel
  2. La vitesse. Bien que je sois sûr que cela peut être argumenté, le profilage que j'ai vu des clous Haskell près de C++ (et semble être un peu plus rapide qu'Erlang).
  3. La vitesse. Le serveur Web Warp semble être rapide et fou par rapport à pratiquement tout le reste .

Donc, étant donné cela, ce que je recherche, ce sont les inconvénients ou les problèmes qui accompagnent Haskell. Le Web contient énormément d'informations sur les raisons pour lesquelles Haskell est une bonne chose, mais je n'ai pas trouvé beaucoup de sujets sur son côté laid (à part les reproches sur sa syntaxe dont je ne me soucie pas du tout).

Un exemple de ce que je recherche pourrait être le GIL de Python. Quelque chose qui n'a pas fait son apparition jusqu'à ce que je commence vraiment à chercher à utiliser la concurrence dans un environnement CPython.

47
Demian Brecht

Quelques inconvénients auxquels je peux penser:

  • En raison de la nature de la langue et de ses racines solides dans le monde universitaire, la communauté est très soucieuse des mathématiques; si vous êtes une personne pragmatique, cela peut parfois être écrasant, et si vous ne parlez pas le jargon, vous aurez plus de mal qu'avec de nombreuses autres langues.
  • Bien qu'il existe une richesse incroyable de bibliothèques, la documentation est souvent laconique.
  • Les didacticiels d'entrée de gamme sont peu nombreux et difficiles à trouver, de sorte que la courbe d'apprentissage initiale est assez abrupte.
  • Quelques fonctionnalités linguistiques sont inutilement maladroites; un exemple frappant est la façon dont la syntaxe d'enregistrement n'introduit pas d'étendue de dénomination, il n'y a donc aucun moyen d'avoir le même nom de champ d'enregistrement dans deux types différents dans le même espace de noms de module.
  • Haskell utilise par défaut une évaluation paresseuse, et bien que ce soit souvent une bonne chose, cela peut parfois vous mordre de façon désagréable. Utiliser une évaluation paresseuse naïvement dans des situations non triviales peut entraîner des goulots d'étranglement inutiles, et comprendre ce qui se passe sous le capot n'est pas exactement simple.
  • L'évaluation paresseuse (surtout combinée avec la pureté et un compilateur optimisant de manière agressive) signifie également que vous ne pouvez pas facilement raisonner sur l'ordre d'exécution; en fait, vous ne savez même pas si un certain morceau de code est réellement évalué dans une situation donnée. Par conséquent, le débogage du code Haskell nécessite un état d'esprit différent, ne serait-ce que parce que parcourir votre code est moins utile et moins significatif.
  • En raison de la pureté de Haskell, vous ne pouvez pas utiliser d'effets secondaires pour faire des choses comme les E/S; vous devez utiliser une évaluation paresseuse monade et "abusive" pour atteindre l'interactivité, et vous devez faire glisser le contexte monadique partout où vous voudrez peut-être faire des E/S. (C'est en fait une bonne fonctionnalité à bien des égards, mais cela rend le codage pragmatique parfois impossible.)
48
tdammers

La plupart des inconvénients de Haskell (ainsi que la plupart des avantages de Haskell) proviennent de ses deux caractéristiques déterminantes: il est paresseux et purement fonctionnel.

Être paresseux, il est plus difficile de raisonner sur les performances. Surtout pour les personnes non habituées à la paresse, mais même pour les Haskellers expérimentés, il peut être difficile de voir comment la paresse affectera les performances dans certains cas.

La paresse signifie également qu'il est plus difficile de créer des repères précis sans utiliser des bibliothèques comme Criterion.

Être purement fonctionnel signifie que chaque fois que vous devez utiliser des structures de données mutables (dans les cas où il n'est pas possible d'atteindre les performances souhaitées sans elles - bien que grâce à l'optimiseur de GHC qui ne se produit pas aussi souvent que vous le pensez), vous serez coincé dans la monade IO (ou ST), ce qui rend le code plus lourd.

Puisque vous avez mentionné la vitesse comme l'un de vos objectifs, je dois souligner qu'il existe souvent d'énormes différences de performances entre le code Haskell optimisé à la main et le code Haskell qui a été écrit sans trop réfléchir aux performances (plus que dans d'autres langues). Et le code Haskell optimisé à la main est souvent assez moche (bien que je suppose que cela soit également vrai dans la plupart des autres langues).

19
sepp2k

Je ne suis pas un expert Haskell: j'ai appris les bases mais malheureusement je n'ai pas eu la chance de faire un projet sérieux à Haskell (j'aimerais bien, car j'aime beaucoup cette langue).

Cependant, d'après ce que je sais et d'une discussion avec quelqu'un qui a travaillé dans un domaine assez proche de la programmation fonctionnelle, Haskell n'est peut-être pas la meilleure solution lorsque vous souhaitez implémenter des algorithmes graphiques, où vous avez besoin par exemple pour parcourir le graphique et effectuer de nombreux changements locaux sur la structure du graphique.

Puisqu'un graphique n'a pas de structure récursive en général, mon sentiment est que la meilleure approche est de construire une copie du graphique en utilisant des structures et des pointeurs entre eux (comme vous pouvez le faire par exemple en C++) et de manipuler cette copie en changeant de pointeurs, créer ou détruire des nœuds, etc.

Je me demande comment ces structures de données et ces opérations peuvent être gérées correctement dans Haskell, car à ma connaissance dans Haskell, il n'est pas possible d'utiliser la représentation/approche ci-dessus. Certains problèmes avec les algorithmes de graphes dans Haskell sont brièvement discutés dans cet article

[~ # ~] modifier [~ # ~]

J'ai récemment parlé à un expert de la programmation fonctionnelle et il a confirmé que la mise en œuvre efficace de certains algorithmes de graphe peut être assez délicate dans Haskell: se déplacer parmi les pointeurs comme vous le faites en C ou C++ peut être beaucoup plus rapide.

12
Giorgio

L'inconvénient de Haskell est que c'est différent. C'est un pas de plus par rapport aux langues qui sont le plus souvent enseignées ou parlées, il y aura donc une courbe d'apprentissage plus longue. Il est également moins populaire d'une langue qui peut limiter la disponibilité de l'aide si vous êtes bloqué. Ce ne sont vraiment pas des inconvénients majeurs.

La seule chose qui est un inconvénient potentiel est qu'il s'agit d'un langage fonctionnel, il est donc moins utile pour certains domaines problématiques, mais cela est également vrai pour les langages orientés objet. Généralement, les langues n'ont pas de vrais négatifs au-delà des courbes d'apprentissage, du moins pour les langues relativement populaires. Tant qu'un langage est Turing complet, il est théoriquement capable de tout.

4
Ryathal

Donc, étant donné cela, ce que je recherche, ce sont les inconvénients ou les problèmes qui accompagnent Haskell

Les "problèmes avec Haskell" ont tendance à apparaître dans certains domaines. Haskell est un langage merveilleux pour la programmation d'applications, beaucoup plus agréable à écrire que n'importe quoi d'autre. Les problèmes ont tendance à surgir lorsque vous essayez de faire quelque chose pour lequel il n'y a pas un bon soutien, comme:

  • Compilation croisée. GHC peut être construit comme un compilateur croisé, mais le processus est plutôt impliqué.
  • Applications embarquées. Haskell a la gestion de la mémoire via un garbage collector, donc celui-ci n'est pas trop surprenant.
  • La vitesse. Haskell n'est pas aussi rapide que Rust, mais dans la plupart des cas, il sera assez compétitif. Cela dépend fortement du domaine d'application - les calculs purs sont bien optimisés, mais quelque chose comme "lire un fichier dans un tampon et compter le nombre de lignes" est plus difficile à exprimer dans Haskell.
0
user275647