Holy freebies, batman, it’s May and we still haven’t started charging for private repos… Yep, it’s taking patch-tag longer to get the commercial ball rolling than planned. Hope nobody minds.

For now, matt and I are focused on improving usability and working out our payments functionality.

The biggest change is a new repo browser. Patch-tag no longer relies on gitit, though we are using a modified filestore module. How this came to be, and what it means for patch-tag users and pour future plans is a topic I hope to address in another blog post. The short and sweet is that I am a lot happier with the feel of repository browsing, and I think it was worth the work to switch from a pure open source community system.

In other news, swayed by recent developments in the darcs world, the ghc project has put their plans for switching from darcs to git indefinitely on hold.


Git’s market is still 30X that of darcs according to google’s research tools, but definitely a shot in the arm for the “other” dvcs.

I just reinstalled ubuntu on my development laptop because the hard drive seems to have been hosed after a hard reboot. (Wubi is vulnerable to those.)

Everything was backed up on patch-tag, so no major drama.

One annoyance was the cabal install I ran for installing patch-tag was getting hung up on some dependency related to this issue


only the advice in that thread didn’t help me, since the error I was getting was that

cabal: dependencies conflict: ghc-6.10.1 requires base ==4

uninstalling base seemed like a bad idea, and I knew that this installer had succeed elsewhere.

So, I sshed in to another box where the install had worked, and ran the following script to determine the *exact* package versions that patch-tag was using by doing

ghc-pkg field patch-tag depends

I specified the exact versions (== for every package dependency) in the cabal file in my new virgin environment, and the problem went away.


Hopefully this kind of annoyance will just go away as cabal keeps gettin the kinks worked out and the haskell platform begins a reality.

I just made my first patch to the darcs source, a minor fix correcting an incorrect help message that has always bugged me.


Stuff I have learned:

There are two different build systems with darcs: cabal and make.

Cabal install does the usual thing

Make is what you want if you want to load darcs into ghci. You need to run autoconf first, which means you need autoconf installed — apt-get install autoconf on debuntu. Then just autoconf; configure; make ghci.

Beter to hack on darcs during daytime pacific time, when there are people on the #darcs channel to answer questions. It’s a lot of code to grok!

I was browsing the FileStore code and got to thinking that the FileStore data type rubbed me the wrong way because it hides IO, diluting the Purity of Essence of haskell’s precious type system.

In ghci of our code that uses FileStore:

:t darcsFileStore "/home/thartman/patchwiki/wikis/happstacktest/"
darcsFileStore "/home/thartman/patchwiki/wikis/happstacktest/" :: FileStore

I see that and I think, cool, a pure value.

Then I think — oops, wrong.

data FileStore
= FileStore {initialize :: IO (),
save :: forall a.
(Contents a) =>
ResourceName -> Author -> Description -> a -> IO (),
retrieve :: forall a.
(Contents a) =>
ResourceName -> Maybe RevisionId -> IO a,
delete :: ResourceName -> Author -> Description -> IO (),
rename :: ResourceName
-> ResourceName
-> Author
-> Description
-> IO (),
history :: [ResourceName] -> TimeRange -> IO [Revision],
latest :: ResourceName -> IO RevisionId,
revision :: RevisionId -> IO Revision,
index :: IO [ResourceName],
idsMatch :: RevisionId -> RevisionId -> Bool,
search :: SearchQuery -> IO [SearchMatch]}

Now I think, aha, this is OO in haskell.

So, what would I want instead?

First idea: how about something like

type FileStore = [resourceName] -- pure

and then a class of RepoAble or something like that which has a bunch of pure methods that must be implemented for any concrete instance of the class. (revision, latest, retrieve, history, index, idsMatch, search)
Then you would have some unavoidably impure methods like save, delete, rename.

Concrete instances could then be defined for Darcs, Git, Svn, etc. You basically have a nice wrapper over various types of repos.

On second thought though, maybe not such a good idea. To have everything work purely after an initial fetch, the FileStore value would have to contain everything in the repo. Nah.

I just want that darned FileStore value tagged with the IO type somehow so I can tell visually when looking at the code that we’re in impure land.

This is when I realized my mistake.

Since all the fields in FileStore are functions, there’s nothing impure about it after all. If one of the fields of fileStore had a concrete value related to a repo, this would smell wrong, because we’re mixing pure and impure — but that’s not the case here.

I think the confusion for me is that I am used to seeing “interfaces” in haskell defined in terms of implementation of a type class, but here the interface is just the arbitrary fields of a datatype, which I think is a bit less type safe.

So, I still think FileStore could be improved that way by taking advantage of typeclassing, but it’s not a matter of it being impure like I initially thought.

Oh boy howdy! Patch-tag just got a bunch of new features.

For starters, we have repo browsing built on gitit. This may sound like an easy thing to do, and we sure thought it would be before actually doing it, but it turned out to be quite a chore. Gitit has some memory issues, and no user permissioning model whatsoever. But we duked the memory issues out with the haskell profiler, cobbled together user permissioning with some help from Benja Fallenstein, and now… it works!

Well, browsing works, diffs works, and there’s a sane repo history viewer. Still no wikis. But we’ll get wikis working soon, too, you’ll see.

You can now browse private repositories with gitit too.

Also pushed:

Better error handling for emails, so hopefully no more severely belated registration emails.

Repo view is better.

You can no longer delete a repo by accidentally clicking the delete link. It’s now a submit button, and even that has a nag screen that tries to convince you that repo deletion is a Bad Thing.

Did I forget anything?

Oh, we ended phase wild alpha: unlimited users may now sign up.

Finally, some bad news for our few 1 users… you know who you are, you all got emails. It’s official now. We are phasing out Darcs 1. Existing darcs 1 repos still work for now, but we turned off creation of new darcs 1 repos, and are encouraging… well, forcing, everyone to move to darcs 2. In a bit — don’t worry, there’s still time. On the plus side, darcs 2 is better than darcs 1 in almost every way, so you should actually send us flowers and candy for twisting yalls arms. In all seriousness, dropping Darcs 1 was a tough call but we are being realistic. We have very ambitious plans for patch-tag, and serving multiple versions of darcs just seemed like something that would bog us down that very few people actually used, and the ones that did use it arguably shouldn’t be. To enjoy a beautiful garden, one must sometimes prune.

So, anyway — behold the new and improved Patch-Tag.


To provide a wiki editing mechanism for repositories in Patch-Tag — which should eventually work for both darcs and git repos — we are adopting Gitit to our purposes by adding a security model with read and edit permissions for wikis, and making it posible for gitit to host more than one wiki at a time.

Overall development is proceeding smoothly, but one decision I regret is having used ImplicitParams for global-ish variables in the first version of our tweak.

ImplicitParams are evil!

They are evil in the same way that global variables are evil. It’s tempting to use them, because they seem to reduce some types of boilerplate. But it just takes a very few steps along that path before understandability becomes seriously impacted.

In fact, one of the best explanations i have seen of ImplicitParams (which actually argues for their goodness) is that IPs make it possible to have global variable-like behavior in haskell without using IOrefs, or other less tractable haskell98 solutions.

But when I look at the way we are using ImplicitParams in our gitit tweak, I am concluding that we shouldn’t be using IORefs *or* ImplicitParams, and basically should be staying away from globals altogether.

The bits of our program that are global-ish — basically configuration information for wiki requests and template key-value information for wiki display — should just be passed as a normal argument to the functions that need it. It’s a bit more wordy, but it tags every function that uses “global-ish” variables clearly, and I’ll take a big increase in understandability for a slight decrease in conciseness.

Exhibit A:

type ParamsHandler = (?params :: Params) => Handler

withMessages :: [String] -> ParamsHandler -> ParamsHandler
withMessages msgs val =
let ?params = ?params { pMessages = msgs ++ pMessages ?params }
in val

I look at this, notice that val doesn’t use anything defined in the let clause, and my brain shuts down.

Without implicit params:

withMessages :: Params -> [String] -> (Params -> Handler) -> Handler
withMessages params' msgs hndlr =
let params = params' { pMessages = msgs ++ pMessages params' }
in hndlr params

Maybe it’s just me, but I find the latter version much easier to understand.

Does anybody use git or darcs for versioning anything other than source code?

Personally, I version resumes and job applications, pictures of myself for quick avatar uploading (this is not all that clever given the alternatives of flickr / picassa, it’s just something I fell into), and craigslist postings for private purposes such as room rentals.

I guess it gives me peace of mind to be able to go back to an earlier version of something I was working on, regardless of whether it’s in a computer language or a human language. Am I weird?


Get every new post delivered to your Inbox.