четверг, октября 24, 2013

Do not mix tabs and spaces

After participating in peer assessment at Coursera's Programming languages I formulated one very common problem: mixing tabs and spaces.

Original post at Coursera's proglang discussion forum is here.

If student writes his code in editor which inserts tabs as is (as '\t' character) it is OK. However when student starts to add extra formatting with spaces (e.g. align if, then and else) his code becomes a problem. Look at the example with tab width 4 (tabs are shown as ->, spaces as spaces):

fun foo x =
--->let val abs = if x > 0
--->--->--->--->  then x
--->--->--->--->  else -x
--->in
--->--->(* ... *)
--->end

And see what happens when another student opens this code with tab width 2:

fun foo x =
->let val abs = if x > 0
->->->->  then x
->->->->  else -x
->in
->->(* ... *)
->end

then and else lines become unaligned and in complicated functions with nested case/if expressions it's very confusing.

There are 2 solutions for this problem:

  • Do not use tabs for alignment. In such case given example should look like:

    fun foo x =
    --->let val abs = if x > 0
    --->              then x
    --->              else -x
    --->in
    --->--->(* ... *)
    --->end
    

    Thus your code will look great with any tab width (e.g. 2):

    fun foo x =
    ->let val abs = if x > 0
    ->              then x
    ->              else -x
    ->in
    ->->(* ... *)
    ->end
    

    But it's quite hard to format code like this without help of your editor (however there are plugins for Vim/Emacs and other IDEs, maybe not perfectly working).

  • Do not use tabs at all. It means to insert needed amount of spaces instead of tab character ('\t'). And the example:

    fun foo x =
        let val abs = if x > 0
                      then x
                      else -x
        in
            (* ... *)
        end
    

    Thus your code will look identically with any tab width. This may be uncomfortable for some of you but this solution guarantees ideal formatting of your code in any possible editor.

    All editors support such mode of inserting spaces when you hit tab:

    • Vim: add set expandtab to ~/.vimrc.
    • Emacs: add (setq-default indent-tabs-mode nil) to ~/.emacs.
    • ... google for your favourite editor.

For more information you may google "tabs vs spaces" and visit this links:

P.S. I will add link to this post in the overall feedback field when I see this problem while assessment.