Languages with explicit scoping encourage you to repeat yourself.

When the talk falls on significant whitespace, the most common reaction I hear seems to be one of nervous apotropaic deflection.

"Indentation matters? Oh, no! I'm horrified."

I've always wondered why people react like that. What's the problem with significant whitespace?

If given a choice, I'd prefer indentation to matter. In that way, I don't have to declare scope more than once.

Explicit scope #

If you had to choose between the following three C# implementations of the FizzBuzz kata, which one would you choose?

a:

class Program
{
static void Main()
{
for (int i = 1; i < 100; i++)
{
if (i % 15 == 0)
{
Console.WriteLine("FizzBuzz");
}
else if (i % 3 == 0)
{
Console.WriteLine("Fizz");
}
else if (i % 5 == 0)
{
Console.WriteLine("Buzz");
}
else
{
Console.WriteLine(i);
}
}
}
}

b:

class Program
{
    static void Main()
    {
        for (int i = 1; i < 100; i++)
        {
            if (i % 15 == 0)
            {
                Console.WriteLine("FizzBuzz");
            }
            else if (i % 3 == 0)
            {
                Console.WriteLine("Fizz");
            }
            else if (i % 5 == 0)
            {
                Console.WriteLine("Buzz");
            }
            else
            {
                Console.WriteLine(i);
            }
        }
    }
}

c:

class Program { static void Main() { for (int i = 1; i < 100; i++) { if (i % 15 == 0) { Console.WriteLine("FizzBuzz"); } else if (i % 3 == 0) { Console.WriteLine("Fizz"); } else if (i % 5 == 0) { Console.WriteLine("Buzz"); } else { Console.WriteLine(i); } } } }

Which of these do you prefer? a, b, or c?

You prefer b. Everyone does.

Yet, those three examples are equivalent. Not only do they behave the same - except for whitespace, they're identical. They produce the same effective abstract syntax tree.

Even though a language like C# has explicit scoping and statement termination with its curly brackets and semicolons, indentation still matters. It doesn't matter to the compiler, but it matters to humans.

When you format code like option b, you express scope twice. Once for the compiler, and once for human readers. You're repeating yourself.

Significant whitespace #

Some languages dispense with the ceremony and let indentation indicate scope. The most prominent is Python, but I've more experience with F# and Haskell. In F#, you could write FizzBuzz like this:

[<EntryPoint>]
let main argv =
    for i in [1..100] do
        if i % 15 = 0 then
            printfn "FizzBuzz"
        else if i % 3 = 0 then
            printfn "Fizz"
        else if i % 5 = 0 then
            printfn "Buzz"
        else
            printfn "%i" i
    0

You don't have to explicitly scope variables or expressions. The scope is automatically indicated by the indentation. You don't repeat yourself. Scope is expressed once, and both compiler and human understand it.

I've programmed in F# for a decade now, and I don't find its use of significant whitespace to be a problem. I'd recommend, however, to turn on the feature in your IDE of choice that shows whitespace characters.

Summary #

Significant whitespace is a good language feature. You're going to indent your code anyway, so why not let the indentation carry meaning? In that way, you don't repeat yourself.



Wish to comment?

You can add a comment to this post by sending me a pull request. Alternatively, you can discuss this post on Twitter or somewhere else with a permalink. Ping me with the link, and I may respond.

Published

Monday, 04 May 2020 10:02:00 UTC

Tags



"Our team wholeheartedly endorses Mark. His expert service provides tremendous value."
Hire me!
Published: Monday, 04 May 2020 10:02:00 UTC