One document about Go

Nick Sabalausky a at a.a
Tue Jun 1 17:38:52 PDT 2010


"Steven Schveighoffer" <schveiguy at yahoo.com> wrote in message 
news:op.vdm3e1fbeav7ka at localhost.localdomain...
> On Wed, 02 Jun 2010 16:50:05 -0400, Alex Makhotin <alex at bitprox.com> 
> wrote:
>>
>> I prefer ANSI(Allman) style(second example, wrong).
>> They want to force Java-like style which I dislike much.
>
> I do too.   You will not find me using go until they change this.
>

This is something I've probably given *way* too much thought to.

First of all, my style is generally like this:

void foo(int num, bool doBigLoop)
{
    if(num < 7)
        writeln("Under 7");

    if(doBigLoop)
    foreach(int x; 0..10)  // Don't do this "stacking" often,
    foreach(int y; 0..10)  // but it's handy once in a while.
    if(x+y < 9)
    {
        writefln("Under 9");

        if(num == x)
            writefln("num == x");
    }
}

I never liked having the opening and closing curly braces not line up. Just 
bugs me. Makes it slightly harder to read too. And even harder still if "} 
else {" is used. I *really* don't like that, when it's used, half the time I 
don't even see the "else".

But, at the same time, the opening-brace-alone-on-it's-own-line often seems 
like a real waste that (visually) stretches the code out needlessly.

So, for a language like D, I just use the '{'-on-a-separate-line style and 
just deal with the extra line since it seems to be the lesser of the evils. 
Sometimes it helps readability with long functions anyway.

Now, I was happy with that for a long time, but now that I'm learning and 
loving a lot of functional-like stuff, I'm more and more coming across 
situations like this:

void funcWithLongHeader(SomeTempl!int alpha, SomeTempl!int beta, 
SomeTempl!int gamma, SomeTempl!int delta, int SomeTempl!epsilon = 
epsilonDefault)
{
    auto foo = [["a":1, "b":2, "c":3], ["z1":0, "z2":7, "z3":4], ["hi":5, 
"b":3, "c":3]];

    if(alpha + beta == 0 || beta + gamma == 3 || gamma + delta == 6 || alpha 
= beta + gamma)
    {
        writeln("Whee");
        whatever();
    }

    someHighOrderFunc((int i) { if(i==77) return 1; else return i; });
}

Obviously I have to add some newlines in there, but how should I do it? I 
could stay consistent with my curly-brace usage:

void funcWithLongHeader
(
    SomeTempl!int alpha, SomeTempl!int beta,
    SomeTempl!int gamma, SomeTempl!int delta,
    int SomeTempl!epsilon = epsilonDefault
)
{
    auto foo =
    [
        ["a":1, "b":2, "c":3],
        ["z1":0, "z2":7, "z3":4],
        ["hi":5, "b":3, "c":3]
    ];

    if
    (
        alpha + beta == 0 || beta + gamma == 3 ||
        gamma + delta == 6 || alpha = beta + gamma
    )
    {
        writeln("Whee");
        whatever();
    }

    someHighOrderFunc
    (
        (int i)
        {
            if(i==77)
                return 1;
            else
                return i;
        }
    );
}

The arrays look ok. The lambda looks maybe a bit too spread out. The rest 
looks like crap.

I could do this:

void funcWithLongHeader(
    SomeTempl!int alpha, SomeTempl!int beta,
    SomeTempl!int gamma, SomeTempl!int delta,
    int SomeTempl!epsilon = epsilonDefault)
{
    auto foo = [
        ["a":1, "b":2, "c":3],
        ["z1":0, "z2":7, "z3":4],
        ["hi":5, "b":3, "c":3]
    ];

    if(alpha + beta == 0 || beta + gamma == 3 ||
        gamma + delta == 6 || alpha = beta + gamma)
    {
        writeln("Whee");
        whatever();
    }

    someHighOrderFunc(
        (int i)
        {
            if(i==77)
                return 1;
            else
                return i;
        }
    );
}

That looks a little better, but there's still some issues. The closing 
parenthesis on the function header and the if statement are difficult to 
see. Also, terms in the if conditional are all misaligned now, and in a way 
that can't be solved in a cross-editor way without eliminating all tabs 
(which shows a blatant disregard for other people's indentation 
preferences), or using a very careful, deliberate and brittle mix of spaces 
and tabs.

Also, that now introduces an annoying bit of inconsistency: some grouping 
symbols start at the end of a line, and others exist on a newline. Parts of 
it look very Java-style, and other parts look very non-Java-style. So at 
this point, I can't help thinking: Why not just take the plunge and go 
'always-at-the-end-of-the-line' all the way? And while I'm at it, I'll put 
the closing-parenthesis at the start of a new line, just like a closing 
curly-brace:

void funcWithLongHeader(
    SomeTempl!int alpha, SomeTempl!int beta,
    SomeTempl!int gamma, SomeTempl!int delta,
    int SomeTempl!epsilon = epsilonDefault
) {

    // snip

    if(
        alpha + beta == 0 || beta + gamma == 3 ||
        gamma + delta == 6 || alpha = beta + gamma
    ) {

        writeln("Whee");
        whatever();
    }

    // snip
}

Eeeww!!!

Also, note that I haven't even tossed call-chaining or templates into the 
mix.

So at this point, I'm convinced that there is no ideal indentation style for 
C/D/Java-style languages. So what about different languages?

If you adopt a LISP-like style, you could have vertically-aligned-braces and 
also omit the useless "opening curly brace" line:

{ if(x+y < 9);
    whatever();
}

But that places much more visual emphasis on the '{' than the 'if', which 
IMO is completely backwards since the 'if' is much more important. In other 
words, too hard to read. And the weird alignment of the 'if' compared to the 
'whatever' is, well...weird.

There's another C-derived natively-compiled language out there (I forget 
what it's called) that has a rather interesting approach. It just simply 
doesn't use (or even allow, AIUI) an opening brace:

if(x+y < 9)
    whatever();
}

It introduces a certain lack of symmetry, and maybe could cause parsing 
problems for certain things (ex, D2-style template constraints probably 
wouldn't work, at least not as-is), but it solves the other problems. 
Although the approach doesn't really scale to parenthesis.

There's BASIC/Perl-style keyword approaches:

if BLAH then
    whatever
end if

if(BLAH)
    whatever
fi

These also have the added bonus of avoiding the following unreadable crap 
that probably every C/D/Java-style programmer is all too familiar with:

                    }
                }
            }
        }
    }
}

But of course, this approach is annoyingly verbose, especially in the case 
of BASIC (why should the ending keywords of a block be more verbose then the 
starting keyword? just seems pointless and unbalanced). And the Perl-style 
approach doesn't scale particularly well to other constructs (such as 
'while' or user-defined constructs).

Then there's the Python approach. But all I'm going to say about that is: 
Those who dislike it already know why they dislike it, and those who do like 
it have probably already heard all the complaints before.

The only conclusion I can come up with is that all syntaxes suck ;)




More information about the Digitalmars-d mailing list