summaryrefslogtreecommitdiffhomepage
path: root/tech/debstablehaskell.mdwn
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2015-11-08 09:43:01 -0700
committerSean Whitton <spwhitton@spwhitton.name>2015-11-08 09:43:01 -0700
commit51b35a9669314710f0be0086de03933dd5ab0c37 (patch)
treea173dede85025d6233de5fad810a0026571fd7d1 /tech/debstablehaskell.mdwn
parent6de270a7f15e6453c74fe11ef279ab93960591a8 (diff)
downloadwiki-51b35a9669314710f0be0086de03933dd5ab0c37.tar.gz
import more pages (badly)
Diffstat (limited to 'tech/debstablehaskell.mdwn')
-rw-r--r--tech/debstablehaskell.mdwn235
1 files changed, 235 insertions, 0 deletions
diff --git a/tech/debstablehaskell.mdwn b/tech/debstablehaskell.mdwn
new file mode 100644
index 0000000..da3d96d
--- /dev/null
+++ b/tech/debstablehaskell.mdwn
@@ -0,0 +1,235 @@
+As of early 2015.
+
+I'm now [doing
+this](http://funloop.org/post/2015-02-10-using-nix-from-arch.html)
+(under Debian) because some packages I want don't build with Debian
+Wheezy's versions of happy, alex and GHC.
+
+Rationale
+=========
+
+I'm trying to learn the Haskell programming language, and I'm tripping
+over the `cabal-install` package management system sufficiently often
+that it's putting me off putting time into learning the language. Here
+are my requirements for a development environment I'm willing to learn
+in:
+1. don't leave Debian Wheezy 32-bit;[^1]
+2. minimise how often I have to delete all of `~/.cabal` and `~/.ghc`;
+3. when using cabal sandboxes, again, minimise the number of core
+ libraries that need to get rebuilt in every sandbox;
+4. be simple enough to integrate cleanly with the existing ways I
+ manage my OS installation and the contents of my home directory;
+5. be simple enough that I can understand everything as a Haskell
+ beginner and can get things working (again) quickly and get back to
+ trying to write Haskell.
+
+In this document I will describe the combination of home directory and
+system-wide installations that fit these requirements, and the workflow
+for sorting out packages so that I can get on with trying to make my
+programs do input and output, and other fun Haskell beginner stuff.
+
+Alternative approaches
+----------------------
+
+The following two approaches don't satisfy the requirements given above.
+
+### Do everything manually
+
+This involves having nothing installed system-wide, including the
+Haskell Platform. Install GHC and Cabal in `~/local/src` and then
+install things into their own sandboxes and add the `.cabal-sandbox/bin`
+directories to your `$PATH`. [Someone on reddit
+describes](http://www.reddit.com/r/haskell/comments/2al3vx/how_do_you_avoid_the_cabal_hell/ciw92mp)
+a balance between installing stuff into `.cabal/bin` and having
+sandboxes in which related packages are built and then symlinking those
+directories. But this requires lots and lots of rebuilding over and over
+and lots of manual `$PATH` additions. System-wide Debian packages
+mitigate this.
+
+[This](https://github.com/quchen/cabal-install-bin) might facilitate
+such an approach.
+
+Fails (2), (3) and (4).
+
+### Use a clever automatic sandboxing solution
+
+[Halcyon](http://halcyon.sh/) and the [Nix package
+manager](https://ocharles.org.uk/blog/posts/2014-02-04-how-i-develop-with-nixos.html)
+(which doesn't require the full NixOS) are the projects I've come across
+that try to do this. They aim to avoid even more rebuilding than my
+approach avoids. The Halcyon author [doesn't want to support 32-bit
+Debian](https://github.com/mietek/halcyon/pull/45), and I don't want to
+be a Nix early adoptor at the same time as trying to learn how to get my
+programs to take input and produce output.
+
+Fails (1) and (5).
+
+Drawbacks of my approach
+------------------------
+
+We're living very far away from the edge: we're using GHC 7.4 and a
+version of the Haskell Platform from 2012. [Someone on reddit
+expresses](http://www.reddit.com/r/haskell/comments/2al3vx/how_do_you_avoid_the_cabal_hell/ciwd33h)
+the view that since Haskell moves so fast, you'll end up rebuilding
+everything all the time anyway so you can use your favourite packages
+from Hackage. The only thing we're not getting from the Debian apt
+repositories that we might is `haskell-mode` and `ghc-mod` for Emacs,
+since we can have newer versions of those without repeated building.
+
+We're doing a lot of rebuilding of libraries, and we're only avoiding
+rebuilding those that come with Debian, which will become less and less
+useful as time goes by and Hackage packages depend on newer versions.
+
+This is okay because I'm a Haskell beginner, and I'm not a professional
+software engineer, so even if I stick with learning Haskell it's going
+to take me years before I'm writing anything that needs fancy
+contemporary libraries. And maybe by then the `cabal-install` ecosystem
+will have improved. I basically need Hackage only for building fancy
+things like [Propellor](http://propellor.branchable.com/) and
+[Structured Haskell
+Mode](https://github.com/chrisdone/structured-haskell-mode) so it's okay
+to sandbox those things and do a load of builds.
+
+System setup
+============
+
+Debian packages and dotfiles
+----------------------------
+
+Get all our basic libraries installed system-wide:
+
+``` {.nil}
+# apt-get install ghc ghc-prof haskell-platform
+```
+
+or if you're using [Propellor](http://propellor.branchable.com/):
+
+``` {.haskell}
+workstationAptPackages :: Property NoInfo
+workstationAptPackages = combineProperties "workstation apt packages"
+ [ Apt.installed ["ghc", "ghc-prof", "haskell-platform"]
+ , Apt.removed ["haskell-mode", "ghc-mod"]
+ ]
+```
+
+Put cabal configuration file in place:
+
+The most important thing here is `require-sandbox: True`. We're not
+putting **anything** in `~/.cabal/bin`. So we need to include all
+`.cabal-sandbox/bin` directories in our `$PATH`. I build stuff that is
+to be built on every machine in `~/local/src`. So for each binary we
+have a sandbox in a directory under `~/local/src`, e.g.
+`~/local/src/propellor`. This code will prepend those directories to
+`$PATH`. It comes from [my
+`~/.shenv`](https://github.com/spwhitton/dotfiles/blob/master/.shenv#L36)
+which is supposed to be a POSIX-compatible script to set up environment
+variables that I can source in `.zshrc`, `.bashrc`, scripts run from
+cron, my GNOME and XFCE startup scripts and wherever.
+
+``` {.bash}
+for bindir in $(find ~/local/src -path "*/.cabal-sandbox/bin"); do
+ PATH="$bindir:$PATH"
+done
+export PATH
+```
+
+Upgrading `cabal-install`
+-------------------------
+
+Before doing anything else, we upgrade `cabal-install`. The version of
+cabal-install in Wheezy is so old that it doesn't know about sandboxes,
+and we don't want to pollute `~/.cabal/bin`. So we cheat and get it from
+Jessie:
+
+``` {.nil}
+# apt-get install -t testing cabal-install
+```
+
+Be sure to have [set up apt
+pinning](http://jaqque.sbih.org/kplug/apt-pinning.html) so that this
+doesn't pull anything else in from Jessie!
+
+Upgrading `cabal-install` again
+-------------------------------
+
+Since we want the smartest dependency resolution we can get, we now
+upgrade cabal to the very latest and greatest.
+
+``` {.nil}
+$ cabal update
+$ cd ~/local/src
+$ cabal get cabal-install
+$ cd cabal-install-*
+$ cabal sandbox init
+$ cabal install
+```
+
+Restart the shell (`hash cabal` isn't enough because we only just
+created the sandbox) and type `cabal --version` to check that the second
+decimal is higher than 20. Use `which cabal` to check that it's the one
+from `~/local/src`.
+
+Usage for Haskell projects
+==========================
+
+Installing other people's programs
+----------------------------------
+
+Maybe you want the `ghc-mod` or `structured-haskell-mode` executables
+from hackage. Follow the procedure just used for upgrading
+`cabal-install` for the second time.
+
+Getting libraries for your project
+----------------------------------
+
+This section is a WIP. But some tips:
+- Basic workflow is `cabal init; cabal sandbox init; cabal build`.
+- Use `cabal repl` to launch ghci.
+- When you need a library, first try to find a debian package (the
+ name will begin with `[lib]ghc-`).
+- If you can't find it, you can use `cabal install blah` to install
+ into the sandbox for testing before adding to the .cabal file as
+ a dependency. Try to install all required packages in one go on one
+ `cabal install blah1 blah2` command as this gives cabal the best
+ chance of getting the dependencies right.
+- Don't be afraid to clear out the sandbox: `rm -rf
+ .cabal-sandbox-config .cabal-sandbox; cabal sandbox init`.
+- Try -v3 to enhance cabal's dependency resolution some more.
+
+Sources & further reading
+=========================
+
+- Useful reddit threads
+ - [How to avoid Cabal
+ Hell](http://www.reddit.com/r/haskell/comments/2al3vx/how_do_you_avoid_the_cabal_hell/)
+ - [Best practices for avoiding Cabal
+ Hell](http://www.reddit.com/r/haskell/comments/2ameew/best_practices_for_avoiding_cabal_hell/)
+- On configuring Emacs
+ - [Using Emacs for Haskell
+ development](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md)
+ -- tools [I
+ use](https://github.com/spwhitton/dotfiles/blob/master/.emacs.d/init-haskell.el)
+ - [Modern Emacs
+ Haskell-Mode](http://blog.hoersten.co/post/110096363794/modern-emacs-haskell-mode)
+ -- more experimental tools if you're willing to break out of
+ Wheezy etc.
+ - [and the reddit
+ thread](https://www.reddit.com/r/haskell/comments/2uspan/modern_emacs_haskellmode/)
+- More advanced stuff
+ - [Comprehensive Haskell
+ Sandboxes](http://edsko.net/2013/02/10/comprehensive-haskell-sandboxes/)
+- Background reading
+ - [How we might abolish Cabal Hell, part
+ 1](http://www.well-typed.com/blog/2014/09/how-we-might-abolish-cabal-hell-part-1/)
+ - [The Cabal of
+ Cabal](http://www.vex.net/~trebla/haskell/cabal-cabal.xhtml) (I
+ think this is out-of-date)
+ - [Storage and Identification of Cabalized
+ Packages](http://www.vex.net/~trebla/haskell/sicp.xhtml)
+
+Notes
+=====
+
+[^1]: Debian Jessie will be out soon, but its versions of GHC and the
+ Haskell platform are still very old so upgrading early is not a way
+ out.