¿Cuál es la diferencia entre Cabal y Stack?

104

Ayer me enteré de una nueva herramienta de Haskell llamada Stack . A primera vista, parece que hace el mismo trabajo que Cabal. Entonces, ¿cuál es la diferencia entre ellos? ¿Es stack un reemplazo para Cabal? ¿En qué casos debería usar Stack en lugar de Cabal? ¿Qué puede hacer Stack que Cabal no pueda?

ZhekaKozlov
fuente
fpcomplete.com/blog/2015/06/announcing-first-public-beta-stack (en resumen, reemplaza cabal-instally usa stackage tanto como sea posible; podría haber alguna integración posterior en cabal-install en algún momento y creo que la comunidad no está segura de si esto es algo bueno o no, porque podría dividir a la comunidad)
Carsten
La pila AFAIU es útil para trabajar rápidamente en un proyecto existente. Si comienzas algo desde cero, ciertamente tendrás que usar cabal.
mb14
@ mb14 Ese no es el caso. Puede utilizar la pila para iniciar proyectos desde cero. De hecho, las plantillas de pila proporcionan una forma sencilla de hacerlo.
Sibi
Consulte este breve artículo para obtener una buena descripción general: scs.stanford.edu/16wi-cs240h/labs/stack.html
michid

Respuestas:

76

¿Es stack un reemplazo para Cabal?

Si y no.

¿En qué casos debería usar Stack en lugar de Cabal? ¿Qué puede hacer Stack que Cabal no pueda?

Stack utiliza los paquetes de apilamiento seleccionados de forma predeterminada . Siendo así, se sabe que las dependencias se construyen juntas, evitando problemas de conflicto de versiones (que, cuando eran algo común en la experiencia de Haskell, solían conocerse como "infierno de cabal"). Las versiones recientes de Cabal también tienen medidas para prevenir conflictos. Aún así, configurar una configuración de compilación reproducible en la que sepa exactamente qué se extraerá de los repositorios es más sencillo con Stack. Tenga en cuenta que también existe una disposición para el uso de paquetes que no son apilables, por lo que puede comenzar incluso si un paquete no está presente en la instantánea de apilamiento.

Personalmente, me gusta Stack y recomendaría a todos los desarrolladores de Haskell que lo usen. Su desarrollo es rápido . Y tiene una UX mucho mejor. Y hay cosas que Stack hace que Cabal aún no proporciona:

  • Stack incluso descarga GHC por usted y lo mantiene en un lugar aislado.
  • Soporte de Docker (que es muy conveniente para implementar sus aplicaciones Haskell)
  • Secuencia de comandos Haskell reproducible : puede identificar la versión de un paquete y puede obtener la garantía de que siempre se ejecutará sin ningún problema. ( Cabal también tiene una función de guión , pero garantizar la reproducibilidad no es tan sencillo).
  • Habilidad para hacer stack build --fast --file-watch. Esto se reconstruirá automáticamente si cambia los archivos locales presentes. Usarlo junto con la --pedanticopción es un factor decisivo para mí.
  • Stack admite la creación de proyectos utilizando plantillas . También admite sus propias plantillas personalizadas.
  • Stack tiene soporte hpack incorporado. Proporciona una forma alternativa (en mi opinión, una mejor) de escribir archivos cabal utilizando el archivo yaml, que se usa más ampliamente en la industria.
  • Intero tiene una experiencia fluida al trabajar con Stack .

Hay una buena publicación en el blog que explica la diferencia: ¿Por qué Stack no es Cabal? Si bien Cabal, en los años intermedios desde esa publicación, ha evolucionado para superar algunos de los problemas discutidos allí, la discusión de los objetivos de diseño y la filosofía detrás de Stack sigue siendo relevante.

Sibi
fuente
¿Ha habido algún cambio desde que se lanzó Cabal 3?
William Rusnack
1
@WilliamRusnack Sí, los hay. Principalmente, el flujo de trabajo predeterminado de Cabal ahora incorpora la prevención de conflictos de dependencia, aunque la estrategia que usa para hacerlo es notablemente diferente de la de Stack. (@Sibi: Me he tomado la libertad de actualizar su respuesta para que refleje mejor cómo están las cosas en estos días.)
duplode
35

En lo que sigue, me referiré a las dos herramientas que se comparan como cabal-install y stack . En particular, usaré cabal-install para evitar confusiones con la biblioteca Cabal , que es una infraestructura común utilizada por ambas herramientas.

En términos generales, podemos decir que cabal-install y stack son interfaces de Cabal . Ambas herramientas permiten crear proyectos Haskell cuyos conjuntos de dependencias pueden entrar en conflicto entre sí dentro de los límites de un solo sistema. La diferencia clave entre ellos radica en cómo abordan este objetivo:

  • De forma predeterminada, cabal-install , cuando se le pida que cree un proyecto, observará las dependencias especificadas en su .cabalarchivo y usará un solucionador de dependencias para encontrar un conjunto de paquetes y versiones de paquetes que lo satisfagan. Este conjunto se extrae de Hackage en su conjunto: todos los paquetes y todas las versiones, pasadas y presentes. Una vez que se encuentra un plan de compilación factible, la versión elegida de las dependencias se instalará e indexará en una base de datos en algún lugar ~/.cabal. Los conflictos de versiones entre dependencias se evitan indexando los paquetes instalados de acuerdo con sus versiones (así como otras opciones de configuración relevantes), de modo que diferentes proyectos puedan recuperar las versiones de dependencia que necesitan sin pisar los dedos de los demás. Este arreglo es lo queLa documentación de cabal-install significa "compilaciones locales al estilo Nix" .

  • Cuando se le pida que cree un proyecto, la pila , en lugar de ir a Hackage, mirará el resolvercampo de stack.yaml. En el flujo de trabajo predeterminado, ese campo especifica una instantánea de Stackage , que es un subconjunto de paquetes de Hackage con versiones fijas que se sabe que son compatibles entre sí. stack luego intentará satisfacer las dependencias especificadas en el archivo (o posiblemente el archivo - formato diferente, la misma función) utilizando solo lo que proporciona la instantánea. Los paquetes instalados de cada instantánea se registran en bases de datos independientes, que no interfieren entre sí..cabalproject.yaml

Podríamos decir que el enfoque de pila intercambia cierta flexibilidad de configuración por sencillez cuando se trata de especificar una configuración de compilación. En particular, si sabe que su proyecto usa, digamos, la instantánea de LTS 15.3, puede ir a su página Stackage y conocer, de un vistazo, las versiones de cualquier pila de dependencias que podrían extraer de Stackage. Dicho esto, ambas herramientas ofrecen características que van más allá de los flujos de trabajo básicos para que, en general, cada una pueda hacer todo lo que hace la otra (aunque posiblemente de una manera menos conveniente). Por ejemplo, hay formas de congelar versiones exactas de una buena configuración de compilación conocida y de resolver dependencias con un estado antiguo de Hackage con cabal-install, y es posible requerir dependencias que no sean de Stackage o anular versiones de paquetes de instantáneas mientras se usa stack .

Por último, otra diferencia entre cabal-install y stack que es lo suficientemente grande como para ser mencionado en esta descripción general es que stack tiene como objetivo proporcionar un entorno de compilación completo, con características como la administración automática de la instalación de GHC y la integración de Docker . En contraste, cabal-install está destinado a ser ortogonal a otras partes del ecosistema, por lo que no intenta proporcionar este tipo de función (en particular, las versiones de GHC deben instalarse y administrarse por separado, ya sea a través de la distribución de Linux paquetes, Haskell Platform Core en Windows o la herramienta ghcup ).

duplode
fuente
11

Por lo que puedo deducir de las preguntas frecuentes, parece que Stack usa la biblioteca Cabal, pero no el cabal.exebinario (más correctamente conocido como cabal-install). Parece que el objetivo del proyecto es el sandboxing automático y evitar el infierno de la dependencia.

En otras palabras, usa la misma estructura de paquete Cabal, solo proporciona una interfaz diferente para administrar estas cosas. (¡Yo creo que!)

MatemáticaOrquídea
fuente
Aparte de cabal, su código fuente también parece estar usando docker. Aunque no sé si lo usan todavía.
Sibi
@Sibi Sí, parece que, opcionalmente, puedes lanzar cosas a Docker, y está destinado a funcionar. No lo he mirado mucho más ...
MathematicalOrchid