kaashif's blog

Programming, with some mathematics on the side

How this blog works

2014-04-13

UPDATE: I now use Hakyll. See http://kaashif.co.uk/about for more. Also, 100% of the information in this blog post is now wrong or outdated.

When I decided I wanted to write a blog, I had to come up with some way of writing posts (in a markup format which isn't HTML), and serving them somehow.

First, I turned to Jekyll, a static blog generator written in Ruby and used by GitHub. That turned out to work quite well, but I wanted more control over the process of post generation. Next, I went for a CGI application written in good old tried-and-tested Perl. That, too worked, but CGI is a bit of a primitive technology, and didn't scale well when I stress-tested it. Next on my list was a Python WSGI app, which ran in a container which served pages. That was OK, and was the most stable incarnation of my website, until I realised how incredibly insecure it was compared to some of the other options I had available. Also, I was getting bored of a solution which worked too well to be any fun.

Obviously, I had the right idea in the first place, with generating static pages, which I could then transfer (using rsync or similar) to a chrooted Nginx server running in a virtual machine (it isn't any more or less secure than running it normally, but it helps me sleep at night), but I couldn't lose face and go back to Jekyll, I'd be humiliated (in my eyes only, though - most other people wouldn't care)! So I had to write a Jekyll clone in a language that was safe, not prone to bugs, had a rich package ecosystem (not unlike the Python package index or Ruby's gems) and was pleasing to write. Obviously, the only sane option was Haskell, and it's the language I chose to write my blog generator in. I called it Muon, because it seems like a cool name - catchy, 4 characters and easy to type.

Getting Muon

At some point, when I consider Muon to be ready for use by normal people, or at least, as normal as a Haskell package user can be, I will upload it to Hackage and you'll be able to install it with a simple:

$ cabal install muon

As it is, you have to get the latest snapshot from my darcs repository. You can still use cabal to install it, though, so dependencies are handled automatically.

$ darcs get http://repos.kaashif.co.uk/muon
$ cd muon
$ cabal install

It might take a while to build the dependencies from source, so if your OS's package manager already has prebuilt binary packages for them, look inside muon.cabal to see what you need to install, and install those.

Using Muon

If you want a quick rundown of what you can do with Muon, have a look at the README file in the darcs repo. If you're too lazy for that, just access Muon's help:

$ muon help

In reality, it doesn't matter what you type as the command - muon outputs a help message for all inputs that aren't already a command. So that's everything other than "generate", "init" and "upload".

It's worth noting that, at the moment, my server is hard coded into Muon's upload command, so you'll have to rsync, scp or FTP the files to your web server yourself, unless you happen to also have a web server called "webserver" serving from /var/www/htdocs, which is entirely possible.

Lessons learnt

Before writing Muon, I had the idea in my head that Haskell was useless for writing anything useful. That is clearly not the case. In fact, I'd say that my Haskell code is cleaner and easier to read (for me) than my Haskell code is cleaner and easier to read by necessity - Haskell's syntax demands it. Also, I find the "name arg = blah $ blah arg" easier to read than "def name(arg): return blah(blah(arg))", due to an allergy to parentheses.

There is always this talk of explaining monads using analogies and shit to make them simpler or easier to understand, but the reality is simple: monads are boxes you put types into. If you have an IO String, it's just a String inside a box labeled IO you have to use \<- and fmap to get at. Once that is realised, you can abandon all of this "monad is a burrito" crap and actually start using them. I'm sure that doesn't count as an analogy, if it does, I'm a complete hypocrite.

Anyway, Haskell isn't too hard to learn. Neither is Common Lisp. It gets really hairy when you move onto Template Haskell and macros in Lisp, but even then, once you get the hang of it, you'll be defining new syntax constructs without much effort.

Happy Haskelling!