Good Haskell Style

Ian Lynagh igloo at earth.li
Wed Aug 1 10:19:59 EDT 2007


Hi all,

I've been sitting on this for four months for various reasons, but Neil
and Duncan keep prodding me to send it, so here it is.

The numbers in the mail are probably out of date by now, due to the
start of the base splitup and general development, but I'm too lazy to
update them.


Thanks
Ian

------------------

Hi all,

My last attempt to write a contentious mail was a miserable failure, so
I'm giving it another go.

I've written up my description and rationale for what makes good Haskell
style. The full thing is at
    http://urchin.earth.li/~ian/style/haskell.html
but I'll copy the conclusion here:

* Don't leave trailing white space in your code
* Don't use tabs
* Aim to keep lines under 80 characters
* Use the CamelCase variable naming convention
* Don't use explicit braces and semicolons

There are also some tips on configuring vim to help out at
    http://urchin.earth.li/~ian/style/vim.html

I think it would be great if we could agree on this (or perhaps some
other) set of style guidelines for the core libraries, and encourage
their use for other libraries.

Future library submissions would be required to follow the guide, and
the existing codebase could either be updated as other changes are made,
or en masse just before the GHC 6.8 fork (to avoid unnecessary patch
merging work).


Just to help motivate the "Don't use tabs" point:

I think someone was saying that they thought that base should use tabs,
as that is what the existing code base uses. Here are some stats which
show that that doesn't seem to be the case; it's hard to draw strong
conclusions without actually manually looking at a large proportion of
the library, but the indication is that 4 spaces is the dominant
indentation. I've attached the script that made the stats.

    Total files:                                       162
    Files where some lines start tab:                  121
    Files where some lines start 4 spaces:             133
    Files where some lines start 8 spaces:             100
    Percentage files where some lines start tab:       74%
    Percentage files where some lines start 4 spaces:  82%
    Percentage files where some lines start 8 spaces:  61%

    Non-blank lines:                            47493
    Lines that start white (white lines):       20584
    Lines that start tab:                       4239
    Lines that start 4 spaces:                  10691
    Lines that start 8 spaces:                  4509
    Percentage non-blank lines start tab:       8%
    Percentage non-blank lines start 4 spaces:  22%
    Percentage non-blank lines start 8 spaces:  9%
    Percentage white lines start tab:           20%
    Percentage white lines start 4 spaces:      51%
    Percentage white lines start 8 spaces:      21%

And a few more stats, just for interest really:

    Lines that have a tab after a space:                                203
    Lines that have a tab after a non-white character:                  2401
    Percentage non-blank lines have a tab after a space:                0%
    Percentage non-blank lines have a tab after a non-white character:  5%


Thanks
Ian, Neil and Duncan

-------------- next part --------------
#!/bin/bash

FILES=(`find . -name "*.hs" -o -name "*.lhs" -o -name "*.hsc"`)

if [ "$1" = "-v" ]
then
    VERBOSE=1
else
    VERBOSE=0
fi

TAB=`printf '\t'`
SPACES4="    "
SPACES8="        "

NUM_FILES=0
FILES_SOME_LINES_START_TAB=0
FILES_SOME_LINES_START_4SPACES=0
FILES_SOME_LINES_START_8SPACES=0

for F in ${FILES[@]}
do
    if [ "$VERBOSE" = 1 ]
    then
        echo $F
    fi
    NUM_FILES=$(($NUM_FILES + 1))
    if grep -q "^$TAB" $F
    then
        FILES_SOME_LINES_START_TAB=$(($FILES_SOME_LINES_START_TAB + 1))
    fi
    if grep -q "^$SPACES4" $F
    then
        FILES_SOME_LINES_START_4SPACES=$(($FILES_SOME_LINES_START_4SPACES + 1))
    fi
    if grep -q "^$SPACES8" $F
    then
        FILES_SOME_LINES_START_8SPACES=$(($FILES_SOME_LINES_START_8SPACES + 1))
    fi
done

LINES_NOT_BLANK=`grep "." ${FILES[@]} | wc -l`
# LINES_START_WHITE=`grep -c "^\\($TAB\\| \\)" ${FILES[@]}`
LINES_START_WHITE=`grep "^[[:space:]]" ${FILES[@]} | wc -l`
LINES_START_TAB=`grep "^$TAB" ${FILES[@]} | wc -l`
LINES_START_4SPACES=`grep "^$SPACES4" ${FILES[@]} | wc -l`
LINES_START_8SPACES=`grep "^$SPACES8" ${FILES[@]} | wc -l`
LINES_TAB_AFTER_SPACE=`grep "^[[:space:]]* $TAB" ${FILES[@]} | wc -l`
LINES_TAB_AFTER_NONWHITE=`grep "^.*[^[:space:]].*$TAB" ${FILES[@]} | wc -l`

echo "Total files:                                      "\
     $NUM_FILES
echo "Files where some lines start tab:                 "\
     $FILES_SOME_LINES_START_TAB
echo "Files where some lines start 4 spaces:            "\
     $FILES_SOME_LINES_START_4SPACES
echo "Files where some lines start 8 spaces:            "\
     $FILES_SOME_LINES_START_8SPACES
echo "Percentage files where some lines start tab:      "\
     $((100 * $FILES_SOME_LINES_START_TAB / $NUM_FILES))%
echo "Percentage files where some lines start 4 spaces: "\
     $((100 * $FILES_SOME_LINES_START_4SPACES / $NUM_FILES))%
echo "Percentage files where some lines start 8 spaces: "\
     $((100 * $FILES_SOME_LINES_START_8SPACES / $NUM_FILES))%

echo

echo "Non-blank lines:                           "\
     $LINES_NOT_BLANK
echo "Lines that start white (white lines):      "\
     $LINES_START_WHITE
echo "Lines that start tab:                      "\
     $LINES_START_TAB
echo "Lines that start 4 spaces:                 "\
     $LINES_START_4SPACES
echo "Lines that start 8 spaces:                 "\
     $LINES_START_8SPACES

echo "Percentage non-blank lines start tab:      "\
     $((100 * $LINES_START_TAB / $LINES_NOT_BLANK))%
echo "Percentage non-blank lines start 4 spaces: "\
     $((100 * $LINES_START_4SPACES / $LINES_NOT_BLANK))%
echo "Percentage non-blank lines start 8 spaces: "\
     $((100 * $LINES_START_8SPACES / $LINES_NOT_BLANK))%

echo "Percentage white lines start tab:          "\
     $((100 * $LINES_START_TAB / $LINES_START_WHITE))%
echo "Percentage white lines start 4 spaces:     "\
     $((100 * $LINES_START_4SPACES / $LINES_START_WHITE))%
echo "Percentage white lines start 8 spaces:     "\
     $((100 * $LINES_START_8SPACES / $LINES_START_WHITE))%

echo

echo "Lines that have a tab after a space:                               "\
     $LINES_TAB_AFTER_SPACE
echo "Lines that have a tab after a non-white character:                 "\
     $LINES_TAB_AFTER_NONWHITE
echo "Percentage non-blank lines have a tab after a space:               "\
     $((100 * $LINES_TAB_AFTER_SPACE / $LINES_NOT_BLANK))%
echo "Percentage non-blank lines have a tab after a non-white character: "\
     $((100 * $LINES_TAB_AFTER_NONWHITE / $LINES_NOT_BLANK))%



More information about the Libraries mailing list