Stack vs Stackage

<p class="date">2016-07-17</p>

Due to their common founding organization, contributors, and naming, stack and Stackage are often con-fused. This note is in response to a request for clarification during a Twitter conversation,

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/a_cowley">@acowley</a> <a href="https://twitter.com/rufuse">@rufuse</a> Could I ask why it&#39;s so important? If you write up a short explanation, I&#39;ll change my slides.</p>&mdash; Domen Kožar (@iElectric) <a href="https://twitter.com/iElectric/status/754689121491292160">July 17, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

1 Stack

stack is a build tool for Haskell projects. It uses a per-project YAML file to identify how to satisfy dependencies. How it goes about doing that is somewhat complicated – it maintains many package databases associated with different versions of the GHC compiler – but the success of the program is that the user seldom needs to be aware of how it works.

2 Stackage

From the Stackage home page,

Stackage is a stable source of Haskell packages. We guarantee that packages build consistently and pass tests before generating nightly and Long Term Support (LTS) releases.

Stackage is a source of package sets that any Haskell build tool can use. A build tool using Stackage will construct build plans (i.e. an association between package names and versions) that is a strict subset of a Stackage package set.

An example use of Stackage is that, today, you might specify that your project's dependencies may be satisfied by Stackage LTS-6.7. If an LTS-6.8 is released, you can – if you wish – update to that to receive backwards-compatible updates and fixes. When breaking changes are introduced, the first component of the LTS version will be incremented. That upgrade may require that you change your code to accommodate changes in a dependency.

The internal consistency of a package set is up to a verification that all packages build together and that their tests pass in a typical Linux environment. This is far from an iron-clad guarantee of correctness, but it frees you from having to deal with the most fundamental dependency incompatibilities.

Compare the above situation to two other common approaches:

  • A rolling release in which hanging back on an upgrade may involve pinning all system libraries to versions with known vulnerabilities
  • A fixed set of versions that you manually curate

Stackage is similar to the latter, except that you get the benefits of a community of users verifying that minor version bumps do not break things. When a version numbering mistake happens in a constituent package, Stackage will hold back on upgrading that package even if its version number suggests it to be backwards compatible, eventually including that change in a major version bump. When a version numbering mistake happens with Stackage itself, there is a public hue and cry and a new version is released at an accelerated schedule.