44

correct:

if(true) {

}

incorrect:

if(true)
{

}

Why is this style enforced, does it have something to do with the language spec, or is it just because they prefer one style over another ?

jokoon
  • 6,207
  • 11
  • 48
  • 85
  • 4
    go's compiler automatically enter all semicolons for you. in incorrect version it will add semicolons after if(true);{} like this which is incorrect. – Akshay Deep Giri Jun 17 '13 at 20:54
  • 2
    The first version is syntactically correct but stylistically bad. The `()` should be used except where needed. see [Effective Go](http://golang.org/doc/effective_go.html#if) – deft_code Jun 18 '13 at 01:00
  • 3
    @deft_code That doesn't make the slightest sense. How would you not use () where they are needed, it's self-contradictory. – Neutrino Apr 28 '14 at 14:56
  • 2
    @deft_code you wrote "should" instead of "shouldn't" – Ryan Haining Jun 17 '14 at 21:02
  • Good catch! Now @Neutrino's comment makes more sense. – deft_code Jun 18 '14 at 01:07
  • What would be really nice would be if there were some way to prevent the Go compiler from adding the semi-colons automatically. Then we'd we able to write nicely formatted code no problem. – Neutrino Jun 18 '14 at 08:43
  • 2
    @Neutrino, the same could be said for C replacing `{` with `then` and `}` to `end`. Then you could write readable C. I think the Go designers made a great decision to end the holy style wars. **Go Shall Have But One Style, And One Style It Shall Have. One Shall Be The Size Of Its Counting. Amen.** This idea has caught one to such an extent that since Go's rise in popularity at Google automatic formatting program have been written for most languages we use. I don't miss being able to customize the indentation/whitespace style of my code. – deft_code Jul 19 '14 at 16:46
  • @deft_code Nothing stops you from doing `#define then {` and `#define end }`. See: `echo 'int main param_list void param_end then return zero end_stmt end' | cpp -D'param_list=(' -D'param_end=)' -D'then={' -D'zero=0' -D='end_stmt' -D'end=}' | grep -v '^#';` `int main ( void ) { return 0 }`. Of course, please don't do it, but you're allowed to do it. :) – alx - recommends codidact Sep 04 '22 at 11:42

5 Answers5

46

Why are there braces but no semicolons? And why can't I put the opening brace on the next line?

Go uses brace brackets for statement grouping, a syntax familiar to programmers who have worked with any language in the C family. Semicolons, however, are for parsers, not for people, and we wanted to eliminate them as much as possible. To achieve this goal, Go borrows a trick from BCPL: the semicolons that separate statements are in the formal grammar but are injected automatically, without lookahead, by the lexer at the end of any line that could be the end of a statement. This works very well in practice but has the effect that it forces a brace style. For instance, the opening brace of a function cannot appear on a line by itself.

http://golang.org/doc/faq#semicolons

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 87
    If it forces a brace style which defeats the point of using braces in the first place (i.e. making it easy to identify scope of statement blocks with braces lined up on same column), then that can hardly be characterised as 'working very well'. Personally I'd prefer to add the semi-colons manually if that meant I could line up braces rationally. A perfect example of the cure being worse than the disease. – Neutrino Jun 18 '14 at 09:04
  • 12
    @Neutrino: I suspect that the go language designers see style enforcement as a good thing. "Constraints are liberating." – maerics Mar 31 '15 at 16:22
  • 15
    Their excuse is bogus. Lua has been using semicolons for code blocks and not requiring semicolons since before Go was even concieved. They could allow other brace styles to be supported but they have explicitly chose not to. Whether it be for the sake of letting them cheat with the parsing or because they decided they were going to force their personal preferences on their userbase, both reasons are bad reasons to lock the users into a single brace style. – Pharap Dec 23 '15 at 04:46
  • 3
    @Pharap: Let alone, braces on a new line are an ANSI standard. K&R is not. But the beauty of standards is that there are so many different ones. InternetExplorer would be a perfect example of that. Additionally, enforcing a style so that code can be better printed is stupid. They should enforce a style that maximally decourages you from printing your code on paper in the first place. Printing code is stupid (what do you want to achieve? Backup?), and it's a security risk, let alone environmental concerns. Additionally, if you want to have code in a specific format, write a beautifier. – Stefan Steiger Mar 31 '16 at 10:04
  • 4
    @StefanSteiger Meh. I've printed code on paper because it's easier to weed through for debugging, walk through complex issues, or to simply red-pen it. Your opinion of stupidity is really harsh and opinionated. #justsayin. – Jim Jun 05 '17 at 21:12
  • 2
    Why don't we write machine code directly? The purpose of a programming language is to make programs easily readable to humans, not machines. Getting a code that is efficient to execute by machines is the purpose of a compiler. I don't care parsing is slow. Those brackets don't help the human eye. Python is more coherent here. – Yugo Amaryl Jun 15 '17 at 04:41
  • I just started to learn Golang and not being able to see clearly where my block of code starts bothers me much. I literally can't read the code if I can't see the opening curly bracket. Let's hope I will somehow get used to it... – Marin Draganov Feb 16 '21 at 17:02
  • 1
    One true brace is sexy. Allman isn't. Braces on a new line are ugly and do nothing except waste and make things difficult to read. I'm saying that as a .NET developer who's forced to look at Allman all day long. The fact that Go is anti-Allman is a massive point in its favour from where I'm standing. You're entitled to your own opinions. – Lumos Apr 21 '22 at 13:40
  • I think ultimately it's mere taste which style you prefer. However, having worked with several dozen ObjC developers on a legacy code base that has been developed for a decade without *any* formatting standards or linting, I've become a big fan of enforced style. Ultimately I think consistency is much more important than having your braces in 1TBS or Allman. – Jan Z. May 09 '23 at 08:25
28

Most C descended languages use the style if ( <condition> ) <statement>, the statement is executed if condition is true. The statement can be either a single statement or brace enclosed block.

Go's if statements require a following brace enclosed block, not a single statement. This is to head off a common error that most style guides try to avoid by requiring that all if statements use braces.

//subtle error in C
if (<condition>)
  <statement1>;
  <statement2>;

Now that Go requires a brace block following the if statement the () are redundant. They only serve to help the lexer differentiate between the condition and the statement, otherwise if <condition> <statement> is hard to parse. (Where does the condition end and the statement begin?)

Now Go's authors have a decision to make:

  • Keep the redundant ()
  • require { to follow the <condition>

They decided redundancy was not desirable. This had a second side effect. Since there is an implicit ; at every newline, if the { is on the following line a ; gets put between the <condition> and the {. Go's authors again are faced with a decision:

  • special case the parser to be smart about the <condition>; { construct
  • require everyone adopt a common style of if ... { on the same line.
  • require that the <condition> be on a single line.

Special casing the parser is a very bad thing. Look at the speed D and Go parsers compared to C++'s terrible parser performance. Also a uniform style is a good thing. Their ultimate decision is pretty simple given the constraints.

Nick Westgate
  • 3,088
  • 2
  • 34
  • 41
deft_code
  • 57,255
  • 29
  • 141
  • 224
  • 1
    why do you compare with d and c++ ? they don't have implicit `;` – jokoon Jun 18 '13 at 11:30
  • Go's `;` insertion uses a non-look-ahead lexer. This is really fast. For performance considerations, implicit `;` is just as fast as explicit `;`. Both **D**, C++, Java, C#, ***Go*** use `;` in their grammar specification and they are **C** descendants (AKA curly brace languages). I compare them because their parsers are similar and had to solve similar problems. – deft_code Jun 18 '13 at 16:05
  • 4
    Why don't we write machine code directly? The purpose of a programming language is to make programs easily readable to humans, not machines. Getting a code that is efficient to execute by machines is the purpose of a compiler. I don't care parsing is slow. Those brackets don't help the human eye. Python is more coherent here. – Yugo Amaryl Jun 15 '17 at 04:43
  • 1
    Braces definitely do help the human eye and Python's significant whitespace is a terrible design choice. The programmer should not have to indent code himself, that should be done automatically by a code formatting tool. – saolof Mar 25 '18 at 17:28
8

It has to do with the Spec, i.e. it's not just something they built into their compilers

Semicolons

The formal grammar uses semicolons ";" as terminators in a number of productions. Go programs may omit most of these semicolons using the following two rules:

When the input is broken into tokens, a semicolon is automatically inserted into the token stream at the end of a non-blank line if the line's final token is

  • an identifier
  • an integer, floating-point, imaginary, rune, or string literal
  • one of the keywords break, continue, fallthrough, or return
  • one of the operators and delimiters ++, --, ), ], or }

To allow complex statements to occupy a single line, a semicolon may be omitted before a closing ")" or "}".

To reflect idiomatic use, code examples in this document elide semicolons using these rules.

As far as I grasped it from their talks, they wanted to get rid of formatting-discussions and extended the idea with the greation of gofmt

Community
  • 1
  • 1
tike
  • 2,234
  • 17
  • 19
  • 1
    If the formal grammar uses semicolons, then why afford people the option to omit them? It seems to me that they sacrificed clarity to appease those who can't be bothered with one keystroke... – Kenny Worden Jun 19 '17 at 15:53
  • 1
    I think Go's rather strict approach to "how to format source code" is a strong benefit of the language. It makes it extremely easy and pleasant to dive into other people's code, esp libraries. When I have to do the same in other languages, e.g. javascript, it often feels like having to learn a "new" subset of the language. The authors intention was to solve the problems that arise from a x billon LOC codebase worked by 10.000 coders aka google scale programming. Often the problem is more about sticking to one way of formatting, rather than finding "the correct way". – tike Jun 23 '17 at 12:34
4

Because the google guys don't like allman style. But it's very easy to support allman style, forkGo(by @diyism) only added 12 lines of code into golang compiler.

Give a try to forkGo: https://gofork.org

forkGo support such allman style:

package main
import
(
    "fmt"
)


func main()
{
    if false
    {   fmt.Println("jack")
        fmt.Println("forkgo")
    } else
    {   fmt/
           .Println("hello")
        fmt.Println("forkgo")
    }
}
diyism
  • 12,477
  • 5
  • 46
  • 46
0

..."he point of using braces in the first place (i.e. making it easy to identify scope of statement blocks with braces lined up on same column), "...

agreed - very difficult if you like to align your braces to distinguish blocks