Saturday, September 12, 2009

How I Use HLint

HLint is a tool for automatically suggesting improvements to your Haskell code. This post describes how I use HLint, and provides and some background on its development. Before reading this article, if you are an active Haskell programmer who has not yet tried out HLint, I suggest you perform the following steps:


cabal update && cabal install hlint
cd your-current-project
hlint . --report
# open report.html in your web browser


The original purpose of HLint was to help teach beginners. When helping with the functional programming course at York, I used to wander round the students, looking at their code, and suggesting improvements. After three years helping with the same course, I found myself regularly suggesting the same improvements. For example, the pattern if a then True else b came up a lot, which can be written more succinctly as a || b. Of course, having turned myself into a pattern recognition tool, the obvious step was to automate myself - and HLint is the result.

I am no longer at a University, and so the way I use HLint has changed. Often on the Haskell Cafe mailing list people ask for code reviews - intermediate level Haskellers trying to gain knowledge from those around them. The suggestions resulting from a code review are often split into two categories. There are small-scale suggestions about things such as using a better library function, and large-scale suggestions about what the structure of the program should be. Often it is useful to tackle the small-scale issues, tidying and polishing what is already there, before investigating any large-scale issues. Unfortunately reviewers are often short of time, so they may not get round to making large-scale suggestions. The hope is that HLint can automate much of the small-scale suggestions, allowing clever people to use their time more effectively on the more complex problems.

Another reason to use HLint is one of developer pride. Some developers do not react well to criticism, and take comments about their code in a very personal way. Worse still, if you declare that some small syntactic pattern is the "wrong way to do it", then you can inadvertently end up just point out the failings. In contrast, if HLint is run first, then the human suggestions are typically deeper, and are design trade-offs that can be debated.

HLint is not designed as a tool to fix existing code, but more as a tool to promote learning, thus pre-emptively fixing future code. I do not intend people to slavishly apply the hints given by HLint - each hint should be carefully considered. For example, the darcs project uses HLint, but has decided that they are not interested in eta reduction hints, so have used HLint's ignoring facility.

One use of HLint is to provide an easy mechanism to start participating in an open source project. One of the largest hurdles in project participation is writing your first patch. Many projects have different conventions and requirements, plus there is usually a large code base that needs to be learnt. A good first step might be to run HLint over the code. While many of the hints suggested by HLint might be design decisions, or minor issues, there are likely to be a few more unambiguous improvements. As a simple example, taking the xmonad code base and applying HLint shows that the import Data.Maybe statements in XMonad\Core.hs could be combined. This would be a perfect first patch for a budding xmonad developer.

HLint can be used in many ways, but my two golden rules for HLint usage are:


  1. Do not blindly apply the output of HLint

  2. Never review code that hasn't had HLint applied

8 comments:

Paulo Sousa said...

I wanted to try HLint, but I really don't know what to do or to install.

I'm a new Ubuntu person.

Thanks for any assistance!

Neil Mitchell said...

Hi Paulo - I'm a Windows user, so don't have any direct experience installing it on Linux. You could try:

* Read this wiki page: http://www.haskell.org/haskellwiki/Cabal/How_to_install_a_Cabal_package
* Ask on the IRC channel: http://www.haskell.org/haskellwiki/IRC_channel
* Ask on the Haskell Cafe mailing list: http://www.haskell.org/mailman/listinfo/haskell-cafe

The people on the IRC and email list are all very friendly, so I'm sure they'll be able to answer your questions.

Thanks, Neil

dixie said...

Heil,

I run hlint on my small tool (LDIF files related) and found following:

Found 384 suggestions (123 errors)

Thanks!

mndrix said...

Thank you. I'd been looking for a tool like this but somehow missed it.

Tom said...

great tool, thanks. What are the areas you think can be improved or you would like to develop more?

Neil Mitchell said...

It's very nice to see people like HLint :-)

Tom: There is always the bug tracker: http://code.google.com/p/ndmitchell/issues/list?q=proj=HLint

But more generally, I'm fairly happy with where HLint is right now, but am always interested in where users think it could go.

Anonymous said...

Paulo, I'd recommend this page to install the Haskell Platform http://hackage.haskell.org/platform/ You should remove (or move) the Haskell (and cabal) you've installed already, and then begin. After that, just add $HOME/.cabal/bin to your $PATH and look at Neil's post again. It worked for me with Ubuntu.

Jlouis said...

HLint is a wonderful little gem. Exactly for the reason you give: It raises the bar for code so the interesting discussions can begin. I've been on and off from Haskell for years and using HLint to get me to remember certain (combinator) idioms is wonderful. Thanks.