Quelle est la différence entre Cabal et Stack?


105

Hier, j'ai découvert un nouvel outil Haskell appelé Stack . À première vue, on dirait qu'il fait à peu près le même travail que Cabal. Alors, quelle est la différence entre eux? La pile remplace-t-elle Cabal? Dans quels cas dois-je utiliser Stack au lieu de Cabal? Que peut faire Stack que Cabal ne peut pas faire?


fpcomplete.com/blog/2015/06/announcing-first-public-beta-stack (en bref, il remplace cabal-installet utilise le stackage autant que possible - il pourrait y avoir une certaine rétro-intégration dans cabal-install à un moment donné et je pense la communauté ne sait pas si c'est une bonne chose ou pas, car cela pourrait diviser la communauté)
Carsten

La pile AFAIU est pratique pour travailler rapidement sur un projet existant. Si vous partez de zéro, vous devrez certainement utiliser la cabale.
mb14

@ mb14 Ce n'est pas le cas. Vous pouvez utiliser stack pour démarrer des projets à partir de zéro. En fait, les modèles de pile constituent un moyen simple de le faire.
Sibi

Voir ce court article pour un bon aperçu: scs.stanford.edu/16wi-cs240h/labs/stack.html
michid le

Réponses:


77

La pile remplace-t-elle Cabal?

Oui et non.

Dans quels cas dois-je utiliser Stack au lieu de Cabal? Que peut faire Stack que la Cabale ne peut pas?

Stack utilise les packages de stackage curés par défaut . Cela étant, toutes les dépendances sont connues pour se construire ensemble, évitant ainsi les problèmes de conflit de version (qui, à l'époque où ils étaient courants dans l'expérience Haskell, étaient connus sous le nom de "l'enfer de la cabale"). Les versions récentes de Cabal ont également mis en place des mesures pour prévenir les conflits. Néanmoins, la configuration d'une configuration de construction reproductible dans laquelle vous savez exactement ce qui sera extrait des référentiels est plus simple avec Stack. Notez qu'il est également prévu d'utiliser des packages non empilables, vous êtes donc prêt à partir même si un package n'est pas présent dans l'instantané de pile.

Personnellement, j'aime Stack et je recommanderais à tous les développeurs Haskell de l'utiliser. Leur développement est rapide . Et il a un bien meilleur UX. Et il y a des choses que Stack fait et que Cabal ne fournit pas encore:

  • Stack télécharge même GHC pour vous et le conserve dans un endroit isolé.
  • Prise en charge de Docker (ce qui est très pratique pour déployer vos applications Haskell)
  • Script Haskell reproductible : vous pouvez identifier la version d'un package et obtenir la garantie qu'il s'exécutera toujours sans aucun problème. ( Cabal a également une fonction de script , mais assurer pleinement la reproductibilité avec elle n'est pas aussi simple.)
  • Capacité à faire stack build --fast --file-watch. Cela se reconstruira automatiquement si vous modifiez les fichiers locaux présents. L'utiliser avec l' --pedanticoption est un facteur décisif pour moi.
  • Stack prend en charge la création de projets à l'aide de modèles . Il prend également en charge vos propres modèles personnalisés.
  • Stack a un support hpack intégré. Il fournit une alternative (IMO, une meilleure) façon d'écrire des fichiers cabales en utilisant un fichier yaml qui est plus largement utilisé dans l'industrie.
  • Intero a une expérience fluide lorsque vous travaillez avec Stack .

Il y a un joli article de blog expliquant la différence: Pourquoi Stack n'est-il pas Cabal? Alors que Cabal a, dans les années qui ont suivi ce poste, évolué de manière à surmonter certains des problèmes discutés, la discussion sur les objectifs de conception et la philosophie derrière Stack reste pertinente.


Y a-t-il eu des changements depuis la sortie de Cabal 3?
William Rusnack le

1
@WilliamRusnack Oui, il y en a. Principalement, le flux de travail Cabal par défaut intègre désormais l'évitement des conflits de dépendance, bien que la stratégie qu'il utilise pour ce faire soit sensiblement différente de celle de Stack. (@Sibi: j'ai pris la liberté de mettre à jour votre réponse afin qu'elle reflète mieux la situation actuelle.)
duplode

35

Dans ce qui suit, je ferai référence aux deux outils comparés en tant que cabal-install et stack . En particulier, j'utiliserai cabal-install pour éviter toute confusion avec la bibliothèque Cabal , qui est une infrastructure commune utilisée par les deux outils.

De manière générale, nous pouvons dire que l' installation et la pile de la cabale sont des interfaces pour Cabal . Les deux outils permettent de construire des projets Haskell dont les ensembles de dépendances peuvent entrer en conflit les uns avec les autres dans les limites d'un seul système. La principale différence entre eux réside dans la manière dont ils abordent cet objectif:

  • Par défaut, cabal-install , lorsqu'on lui demande de construire un projet, examine les dépendances spécifiées dans son .cabalfichier et utilise un solveur de dépendances pour déterminer un ensemble de packages et de versions de packages qui le satisfont. Cet ensemble est tiré de Hackage dans son ensemble - tous les packages et toutes les versions, passées et présentes. Une fois qu'un plan de construction réalisable est trouvé, la version choisie des dépendances sera installée et indexée dans une base de données quelque part dans ~/.cabal. Les conflits de version entre les dépendances sont évités en indexant les packages installés en fonction de leurs versions (ainsi que d'autres options de configuration pertinentes), afin que différents projets puissent récupérer les versions de dépendances dont ils ont besoin sans se marcher sur les pieds. Cet arrangement est ce que lela documentation cabal-install signifie par "versions locales de style Nix" .

  • Lorsqu'on lui a demandé de créer un projet, stack , plutôt que d'aller dans Hackage, regardera le resolverdomaine de stack.yaml. Dans le flux de travail par défaut, ce champ spécifie un instantané de Stackage , qui est un sous-ensemble de packages de piratage avec des versions fixes connues pour être compatibles entre elles. stack tentera alors de satisfaire les dépendances spécifiées dans le fichier (ou éventuellement le fichier - format différent, même rôle) en utilisant uniquement ce qui est fourni par l'instantané. Les packages installés à partir de chaque instantané sont enregistrés dans des bases de données distinctes, qui n'interfèrent pas les unes avec les autres..cabalproject.yaml

Nous pourrions dire que l' approche de la pile échange une certaine flexibilité de configuration pour la simplicité lorsqu'il s'agit de spécifier une configuration de construction. En particulier, si vous savez que votre projet utilise, par exemple, l'instantané LTS 15.3, vous pouvez accéder à sa page Stackage et connaître, d'un coup d'œil, les versions de toute pile de dépendances qui pourraient être extraites de Stackage. Cela dit, les deux outils offrent des fonctionnalités qui vont au-delà des flux de travail de base afin que, dans l'ensemble, chacun puisse faire tout ce que l'autre fait (bien que peut-être d'une manière moins pratique). Par exemple, il existe des moyens de figer les versions exactes d'une bonne configuration de construction connue et de résoudre les dépendances avec un ancien état de Hackage avec cabal-install, et il est possible d' exiger des dépendances non-Stackage ou de remplacer les versions de package d'instantanés lors de l'utilisation de stack .

Enfin, une autre différence entre cabal-install et stack qui est suffisamment importante pour être mentionnée dans cet aperçu est que la stack vise à fournir un environnement de construction complet, avec des fonctionnalités telles que la gestion automatique de l'installation GHC et l' intégration Docker . En revanche, cabal-install est censé être orthogonal à d'autres parties de l'écosystème, et ne tente donc pas de fournir ce type de fonctionnalité (en particulier, les versions de GHC doivent être installées et gérées séparément, que ce soit via la distribution Linux packages, Haskell Platform Core sous Windows ou l’outil ghcup ).


11

D'après ce que je peux glaner dans la FAQ, il semble que Stack utilise la bibliothèque Cabal, mais pas le cabal.exebinaire (plus correctement appelé cabal-install). Il semble que le but du projet soit le sandboxing automatique et d'éviter l'enfer des dépendances.

En d'autres termes, il utilise la même structure de package Cabal, il fournit simplement un frontal différent pour gérer ces choses. (Je pense!)


En dehors de cela cabal, leur code source semble également utiliser docker. Bien que je ne sache pas s'ils l'utilisent encore.
Sibi

@Sibi Oui, il semble que vous puissiez éventuellement ajouter des éléments dans Docker, et cela est censé fonctionner. Je ne l'ai pas regardé beaucoup plus loin ...
MathematicalOrchid
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.