On the length of keywords

On the length of keywords

Is it important to consider the character-width of your keywords? After some conversations with a co-worker I’ve come to believe it is, and it was likely something I had noticed in the past, but not been able to quantify.

Take, for example, Haskell – a language with a syntactic reliance on whitespace/alignment (note: I played around with Haskell for a little while, I’m definitely not competent at it, but it was the first concrete example of the percieved issue I ran into).


    quicksort [] = []
    quicksort (x:[]) = [x]
    quicksort (x:xs) = less ++ [x] ++ more
        where less = quicksort $ filter (< x) xs
              more = quicksort $ filter (> x) xs

The problem: where is 5 characters wide.

Why does this matter? Most people use 4 or 8-wide indentation (whether spaces or tabs), meaning that in a dumb editor you have to hit tab, space, space. Not the end of the world, but annoying – especially as the language requires you indent the next line those 6 spaces.

Although this issue is not visible when reading the code – because Haskell enforces the indentation be aligned – it’s visible when writing.

Let’s take a look at a more visual example, in JavaScript now:


    function quicksort([x, ...xs]) {
        if (xs.length == 0)
            return []
        const less = quicksort(xs.filter(y => y < x))
        const more = quicksort(xs.filter(y => y > x)) 
        return less.concat(x).concat(more)
    }

Notice what happens if we use three-letter keywords:


    fun quicksort([x, ...xs]) {
        if (xs.length == 0)
            ret []
        let less = quicksort(xs.filter(y => y < x))
        let more = quicksort(xs.filter(y => y > x)) 
        ret less.concat(x).concat(more)
    }

To my eyes, the alignment here makes it easier to scan past the ‘meta’ parts of the program – ie. declarations.

I understand that it’s probably not a great idea to restrict your language based on how many spaces people display tabs as, but (to my brain at least) it does have an interesting effect on the way the code reads.

In the above example I’d also like to draw attention the convention of a leaving a space between the if and open-paren gives it a width of 4 characters as well.

Another thing worth taking into account here is that I deliberately chose less and more to emphasis the natural columns that can form inside a program – a more conventional quicksort might’ve used smaller and larger, I do think the length of keyword makes an impact in such scripts also, but the effect seems less obvious:


    fun quicksort([x, ...xs]) {
        if (xs.length == 0)
            ret []
        let smaller = quicksort(xs.filter(y => y < x))
        let larger = quicksort(xs.filter(y => y > x)) 
        ret smaller.concat(x).concat(larger)
    }

Anyway, just an observation, once you start thinking about scaling this up to all the things in a language while keeping to the conventional imperitive keywords it gets messy.


    fun disaster(int param1
                 str param2
                 lst param3): boo {
        boo result = Tru;
        sw (param1) {
        cse 1:
            result = Fal;
        cse 2:
            param3[0] += 10;
            brk;
        cse 3:
            ret Fal;
        }

        print(param2);
        ret result;
    }

:^)