No Allman-Style, No go!

8,287 views
Skip to first unread message

Michael Daconta

unread,
Sep 20, 2013, 9:58:03 PM9/20/13
to golan...@googlegroups.com
Hi Go fans,

I frankly was shocked to learn that a program like:

package main;

import "fmt";

func main() 
{
fmt.Printf("hello, world!\n");
}

... is currently illegal in go with the error:

# command-line-arguments
.\hello.go:6: syntax error: unexpected semicolon or newline before {

From reading the newsgroups, I see that this is illegal due to the automatic insertion of semi-colons; however, what if I added my own semi-colons into the code as in the above.  From a language perspective the above should be legal Go code.  To me, it seems like a hack for convenience (making semi-colons optional) has forced a K&R style on everyone.
For me, this is a show-stopper.  Frankly, I am surprised that Google would enforce a coding style (K&R) while saying that "go fmt" frees you from worrying about divergent coding styles.  Sorry, google - you cannot have it both ways.  Unless the Allman-style code above is illegal in the language (which makes no sense from a language semantics point of view) - get the compiler to accept it. Period.

Yes, I know I can write my own translator - but why?  Heck, I can just stick with Java...

C'mon Google, when trying to pitch a new language, you can (and should) do better than this...

- Mike

Dave Cheney

unread,
Sep 21, 2013, 12:45:58 AM9/21/13
to Michael Daconta, golang-nuts
I, For One, welcome the One True Brace style.
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

minux

unread,
Sep 21, 2013, 12:52:56 AM9/21/13
to Michael Daconta, golang-nuts
The introduction of gofmt is precisely to avoid discussion of relative merits of each one's style.

I think all Go code in one style is much much more important than what that enforced style is.

Cao Nguyên

unread,
Sep 21, 2013, 12:57:04 AM9/21/13
to golan...@googlegroups.com


Vào 08:58:03 UTC+7 Thứ bảy, ngày 21 tháng chín năm 2013, Michael Daconta đã viết:
From a language perspective the above should be legal Go code. 

You mean for all kind of languages in general???

Rob Pike

unread,
Sep 21, 2013, 1:04:55 AM9/21/13
to Cao Nguyên, golan...@googlegroups.com

Liigo Zhuang

unread,
Sep 21, 2013, 1:59:43 AM9/21/13
to Rob 'Commander' Pike, golang-nuts, Cao Nguyên

It was designed to simplify go's compiler programming. It was not designed for programmers' programming.

Rob Pike

unread,
Sep 21, 2013, 2:29:46 AM9/21/13
to Liigo Zhuang, golang-nuts, Cao Nguyên
No, it was designed so the behavior was easy to specify and requires
no look-ahead.

-rob

DisposaBoy

unread,
Sep 21, 2013, 3:42:13 AM9/21/13
to golan...@googlegroups.com
kthxbai

Jan Mercl

unread,
Sep 21, 2013, 3:49:56 AM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 3:58 AM, Michael Daconta
<michael...@gmail.com> wrote:
> Unless the Allman-style code above is illegal in the language
> (which makes no sense from a language semantics point of view) - get the
> compiler to accept it. Period.

Not true. It is precisely defined in the language specification[0]. So
the compiler _must_ reject the syntax error. Period.

[0]: http://golang.org/ref/spec#Semicolons

-j

Michael Daconta

unread,
Sep 21, 2013, 9:28:08 AM9/21/13
to golan...@googlegroups.com, Michael Daconta
Considering go fmt throws the same error, I don't see how that is true.

Here is what "go fmt" does on the same code:
C:\Projects\gosrc>go fmt hello.go
hello.go:6:1: expected declaration, found '{'
exit status 2

So, so much for "go fmt" reformatting legal code into the approved format.  Is this just an error in "go fmt" or an error in the language spec?

- Mike

Michael Daconta

unread,
Sep 21, 2013, 9:33:26 AM9/21/13
to golan...@googlegroups.com, Cao Nguyên
Hi Rob,

In that reference it says, "Go is a new language and gofmt's style is as good as any other."

I totally disagree.  K&R style does not clearly show the alignment of blocks of code as the Allman style does.  That has always been my problem with K&R - the Allman style is more readable.
While it is obvious people disagree and are welcome to their opinion - this should not be something enforced by the language.  The language should enforce the semantics of the tokens, not whether a token should be placed on the current line or the next line.  Rather ridiculous rule if you ask me...  I do believe that will hurt adoption of the language - and, IMO, I think it is a very poor decision on the part of the language designers.

To me, that is akin to shooting yourself in the foot as there are many good alternatives out there.

- Mike

On Saturday, September 21, 2013 1:04:55 AM UTC-4, Rob Pike wrote:
http://golang.org/doc/faq#semicolons

-rob

Michael Daconta

unread,
Sep 21, 2013, 9:35:33 AM9/21/13
to golan...@googlegroups.com, Liigo Zhuang, Cao Nguyên
Since when is a language designed to be easy on the compiler?  Sorry, seems like messed up priorities...

Michael Daconta

unread,
Sep 21, 2013, 9:38:36 AM9/21/13
to golan...@googlegroups.com, Michael Daconta
That proves my point... to make semi-colons optional but required in the spec, therefore requiring the automatic insertion before compilation - they broke the compilation of braces.  In essence, forcing the K&R style for the ease of automatic semi-colon insertion.  My assertion is that this is poor design.

Rémy Oudompheng

unread,
Sep 21, 2013, 9:42:08 AM9/21/13
to Michael Daconta, golan...@googlegroups.com
The original code is illegal: gofmt doesn't format illegal code.

Rémy.

Aram Hăvărneanu

unread,
Sep 21, 2013, 9:41:31 AM9/21/13
to Michael Daconta, golang-nuts, Liigo Zhuang, Cao Nguyên
> For me, this is a show-stopper.

Sorry to hear that Go is not the language for you. I am sure there are
many other languages to chose from.

--
Aram Hăvărneanu

Rémy Oudompheng

unread,
Sep 21, 2013, 9:43:31 AM9/21/13
to Michael Daconta, golan...@googlegroups.com, Cao Nguyên
I'm not sure why you speak using the future sense and say 'this will
hurt adoption of the language'.

The Go 1 syntax is frozen, and the language is already adopted.


2013/9/21, Michael Daconta <michael...@gmail.com>:

Rémy Oudompheng

unread,
Sep 21, 2013, 9:44:44 AM9/21/13
to Michael Daconta, golan...@googlegroups.com, Liigo Zhuang, Cao Nguyên
Since the absence of a working and compliant ompiler makes a whole
language pointless.

Rémy.


2013/9/21, Michael Daconta <michael...@gmail.com>:

Michael Daconta

unread,
Sep 21, 2013, 9:45:24 AM9/21/13
to golan...@googlegroups.com, Michael Daconta
I assume you say this with tongue-in-cheek; however, I cannot believe this design decision was made.  For something to borrow so liberally from C only to enforce "one-true" bracing style is frankly ridiculous.
When someone has coded for a long time using their favorite bracing style, the numerous hours of frustration to learn this new language become not worth it.  Just due to inadvertent, habitually return to a bracing style the language designers deemed improper - which, in fact, is actually due to the laziness of their compiler.  I believe they could improve the compiler to correct this.  So, while I could write my own compiler for this - there is actually an easier solution, just ignore this language until the language designers do the right thing.  And if not, ignore it all together. Though I like many features of the language from looking at the "go tour", I can take it or leave it.

While I new this post could be flame bait, I actually had to post it because I was so shocked that Google would make such a foolish error.  Really, lose adoption over compiler laziness?  Give me a break...

- Mike

Michael Daconta

unread,
Sep 21, 2013, 9:47:54 AM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Remy,

Ok, maybe you can explain to me why putting the brace on the following line is illegal in the language?
Is it because of the auto-semi-colon insertion?  If that is the case, and my semi-colons are all legal in the program - is that not an error in the semi-colon insertion logic?

- Mike

Aram Hăvărneanu

unread,
Sep 21, 2013, 9:48:37 AM9/21/13
to Michael Daconta, golang-nuts
If the brace style drives away people who care about brace styles
beyond everything else, then it's working as intended.

--
Aram Hăvărneanu

Rémy Oudompheng

unread,
Sep 21, 2013, 9:49:42 AM9/21/13
to Michael Daconta, golan...@googlegroups.com
Compiler laziness is a minor argument. Humans must also understand
semicolon insertion rules, justifying the choice of simple rules.

The choice of a standard formatting also makes the use of grep easier.


2013/9/21, Michael Daconta <michael...@gmail.com>:
>> > email to golang-nuts...@googlegroups.com <javascript:>.

Michael Daconta

unread,
Sep 21, 2013, 9:50:31 AM9/21/13
to golan...@googlegroups.com, Michael Daconta, Cao Nguyên
Hi Remy,

Adoption is not a single event... it is an ongoing continuum.
This absolutely will hurt adoption because it is foolish enforcement with no good reason.  It is "because I said so" enforcement.  It may not matter to many people, but it will to some.
So, how much adoption is hurt by it is irrelevant, the fact remains that it will hurt adoption which is why I consider it a poor design choice.

Consider this - such a restriction is not enforced in C (which this language borrows heavily from), not enforced in Java or C# which are also in the same language... so what good reason is it that this was necessary in Go?

- Mike

Michael Daconta

unread,
Sep 21, 2013, 9:53:29 AM9/21/13
to golan...@googlegroups.com, Michael Daconta
Very nice.  LOL.  That may be the case but given "driving away people" is not usually a design choice.  My bet is that you are wrong...  putting it another way, maybe folks who blindly conform to whatever garbage is thrown their way are the type of programmers they are trying to attract!  Join the borg...  LOL

andrey mirtchovski

unread,
Sep 21, 2013, 10:00:28 AM9/21/13
to Michael Daconta, golang-nuts
> Very nice. LOL.

i think you've made your point clear. no action will be taken on it.
can we move on, please?

Michael Daconta

unread,
Sep 21, 2013, 10:04:09 AM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Remy,

So, in the original program, to test the exact theory you mention, I added all the semi-colons myself.
Like so:


package main;

import "fmt";

func main()
{
    fmt.Printf("hello, world!\n");
}

As you can see, the code has semi-colons in each required location.  So, I ask you - why is the above code illegal?
All I've heard so far, is that "it is because the automatic insertion of semi-colons requires this stupid behavior".  Given the above code should require NO automatic insertion of semi-colons - why the stupid behavior?

As for the folks on the thread saying "get over it" - sorry, I would turn the question back to you and say - why are you blindly accepting something so foolish?  There are things in a programming language that MUST be enforced, this should not be one of them.  So, either the language designers must admit their language is poorly designed, or they need to fix the problem!  Ignoring the problem or flippantly asserting there is no problem, is the worst thing they can do as it goes against the very reasons you design a new language for in the first place.

- Mike

John Waycott

unread,
Sep 21, 2013, 10:14:02 AM9/21/13
to golan...@googlegroups.com, Cao Nguyên


On Saturday, September 21, 2013 6:33:26 AM UTC-7, Michael Daconta wrote:
Hi Rob,

In that reference it says, "Go is a new language and gofmt's style is as good as any other."

I totally disagree.  K&R style does not clearly show the alignment of blocks of code as the Allman style does.  That has always been my problem with K&R - the Allman style is more readable.
While it is obvious people disagree and are welcome to their opinion - this should not be something enforced by the language.  The language should enforce the semantics of the tokens, not whether a token should be placed on the current line or the next line.  Rather ridiculous rule if you ask me...  I do believe that will hurt adoption of the language - and, IMO, I think it is a very poor decision on the part of the language designers.

I would like to see evidence that Allman is more readable than K&R. Some people think so, but I've never seen a study that demonstrates better comprehension, fewer bugs, etc when using one style over another.  I have seen bugs due to indentation issues creep into code, however, when a developer edits a code and mixes their preferred style with the style from the original author. That is probably why most coding standards I've seen insist on a consistent style no matter what is used.

I too prefer the Allman style, but I think the Go authors made the correct decision. Go is not C.


Eric Palmer

unread,
Sep 21, 2013, 10:14:47 AM9/21/13
to Aram Hăvărneanu, Michael Daconta, golang-nuts
+1

Sent from my iPhone

Michael Daconta

unread,
Sep 21, 2013, 10:24:03 AM9/21/13
to golan...@googlegroups.com, Cao Nguyên
That is a good point... I don't have proof it is more readable in terms of a study.  For me, it is more readable because it is aligned vertically instead of the more diagonal K&R style.

I don't think it should be one style over another, to be honest, I just don't think it is something that should be enforced in the language.

- Mike

Michael Daconta

unread,
Sep 21, 2013, 10:26:03 AM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Andrey,

You may be right and no action will be taken.  I did feel it necessary to raise the issue though.
Yes, I can move on...

Thanks for listening folks,

- Mike

Volker Dobler

unread,
Sep 21, 2013, 10:51:16 AM9/21/13
to golan...@googlegroups.com
Am Samstag, 21. September 2013 15:50:31 UTC+2 schrieb Michael Daconta:

Adoption is not a single event... it is an ongoing continuum.
This absolutely will hurt adoption because it is foolish enforcement with no good reason.  It is "because I said so" enforcement.  It may not matter to many people, but it will to some.
So, how much adoption is hurt by it is irrelevant, the fact remains that it will hurt adoption which is why I consider it a poor design choice.


And blue bike sheds won't help adoption of bike-to-work
for those who insist on red sheds...

Just stay away if you really cannot cope with Go.

V.

Andy Balholm

unread,
Sep 21, 2013, 11:10:57 AM9/21/13
to golan...@googlegroups.com, Michael Daconta
You can't write Allman-style in Python either. That fact doesn't seem to have hurt the adoption of Python.

Rémy Oudompheng

unread,
Sep 21, 2013, 11:14:02 AM9/21/13
to Michael Daconta, golang-nuts
2013/9/21 Michael Daconta <michael...@gmail.com>:
> Very nice. LOL. That may be the case but given "driving away people" is
> not usually a design choice. My bet is that you are wrong... putting it
> another way, maybe folks who blindly conform to whatever garbage is thrown
> their way are the type of programmers they are trying to attract! Join the
> borg... LOL

I'm not sure who is "they", but it is certain that Go is notably
designed towards corporate programmers.

Rémy.

Michael Jones

unread,
Sep 21, 2013, 12:07:39 PM9/21/13
to Rémy Oudompheng, Michael Daconta, golang-nuts
Hi Michael (from a fellow Michael),

I hope you dig deeper before turning away. Go is a language with an attitude. This is unusual among languages. It's long been common for a programming language to have a "domain" focus: scientific formulas, business charting, string or list processing, and so on. But this is just what you do, not about how you do it. Go's attitudes about how arise from its developer's experience with human problems in software engineering at larger scales, synchronization problems in concurrency at finer scales, and system software problems at Internet scales. 

The formatting attitude seems strange indeed, since the grammar has no inherent problem either way. However, any survey of free form language use will show that everyone has their own style, that commonality of code (diffs of checkins, say) is frustrated by this; the understanding the code of others is hampered by this (more in a moment), and that debates and discussion about styles are rampant. 

The most important of these is in code understanding. Most new programmers and student programmers write, test, and debug a program solo then discard it. All commercial code has a very different lifestyle. The code tends to live for years or decades, it may be written, extended, refactored, bifurcated, and remerged by hundreds of people. It will go in and out of source code control systems millions of times during this interval. It will be edited in hundreds of different tools, seen in hundreds of different fonts, and likely compiled on and for a diversity of hardware systems.

Go's developer's had the experience gained since their roles creation of the C language and UNIX operating system to see all of these real-world software engineering problems. They had seen the effort necessary within the Gnu compiler suite to manage the same problems. Plus, here at Google we have the same issues across a range of languages and platforms. With that as a basis, they set the task of building in hoped-for antidotes to these issues in the language itself. This is the source of the attitude about many things that you will find in Go as you learn more.

For block structure:

1. It is better if block structure is indicated by specific BEGIN and END tokens. Some languages use indentation, but time has shown this convenience to be dangerous when editing and in the software transformation of code bases. Go uses '{' and '}' for these tokens in the C tradition.

2. It is better if block structure is echoed by uniform source code formatting. This helps with checkins and diffs and is essential in understanding code written by others. It can be forced by tools so that formatting happens pre-checkin and post-merge. The choice of style is inherently arbitrary and so was fixed for Go by its designers after discussion.

That's about it. You may well prefer a different structure. As it happens, I agree with you and like the Allman style better; all of my own C and C++ code is that way. However, when it comes to Go, the benefits listed above are why Go is as it is and I have found the benefits to far outweigh the cost of getting used to a new style. It does not take long, and the uniformity of millions of lines of code quickly creates a natural expectation---that's just what Go code looks like.

Michael

P.S. You will find many other examples of Go's attitude as you progress with it. In every case, even if you disagree with a decision, you'll find that there are good reasons and clear benefits for the choices that were made. Hopefully, the more "irritated" you are with aspects of Go's attitude, the more you will learn from those specific aspects. (Lessons about storage management in concurrent applications, lessons about error handling in robust applications, lessons about implicit conversions in expression evaluation, lessons about compiler options for warnings versus errors, and, lessons about unused imports, variables, and other forms of dead code.)


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Michael T. Jones | Chief Technology Advocate  | m...@google.com |  +1 650-335-5765

andrey mirtchovski

unread,
Sep 21, 2013, 12:17:53 PM9/21/13
to golang-nuts
I was going to say "brace indentation consistency is the hobgoblin of
small minds" but just before I did, I googled the phrase and came upon
this article. at least to me it clearly illustrates what Go has
managed to avoid, this thread notwithstanding. it's a good read if
only in the "see what we're missing?!" sense:

http://www.reenigne.org/blog/the-hobgoblin-of-little-minds/

Michael Daconta

unread,
Sep 21, 2013, 12:34:25 PM9/21/13
to golan...@googlegroups.com, Rémy Oudompheng, Michael Daconta
Hi Michael,

Excellent post and I understand your points.  Maybe I'll write a go pre-processor as an exercise...

Regards,

- Mike

Michael Daconta

unread,
Sep 21, 2013, 12:42:06 PM9/21/13
to golan...@googlegroups.com
Hi Andrey,

It may be a minor thing to many, I just don't think it should be something that is enforced because the language should not care where I place the curly braces.
No one who has responded has answered the question on whether this issue is caused by the automatic insertion of semi-colon behavior or if the language spec actually requires K&R.  If it is the former, it is a bug.  If it is the latter, then the language designers are enforcing an arbitrary decision which I maintain is poor design.

So, instead of saying, you shouldn't prefer one form over the other.  The real question is "why are you making me choose?"
Explain that,

- Mike

Rémy Oudompheng

unread,
Sep 21, 2013, 12:48:04 PM9/21/13
to Michael Daconta, golang-nuts
On 2013/9/21 Michael Daconta <michael...@gmail.com> wrote:
> Hi Andrey,
>
> It may be a minor thing to many, I just don't think it should be something
> that is enforced because the language should not care where I place the
> curly braces.
> No one who has responded has answered the question on whether this issue is
> caused by the automatic insertion of semi-colon behavior or if the language
> spec actually requires K&R. If it is the former, it is a bug. If it is the
> latter, then the language designers are enforcing an arbitrary decision
> which I maintain is poor design.

It's both: semicolon insertion is part of the spec. And the rules
enforce that a semicolon is inserted if a line ends with a ')'.

Rémy.

andrey mirtchovski

unread,
Sep 21, 2013, 12:48:25 PM9/21/13
to Michael Daconta, golang-nuts
> Explain that,

that's the real problem: I can't. outside of this thread it's not an
issue that I have. gofmt could, perhaps, but it's a bit hardline in
its reasoning and not a good conversationalist.

Michael Daconta

unread,
Sep 21, 2013, 12:50:57 PM9/21/13
to golan...@googlegroups.com
Ok, I understand your sentiment but you have not answered the question beyond the assertion that "it doesn't matter."

It doesn't matter - to you.  Maybe this is a philosophical point - why would a language design enforce a feature that has no bearing on the compilation of the code?

From a "language-legality standpoint" - 

why is 
func main() { 

legal and 
func main() 
{
 // tbd

not legal?  Both declare a function and both assert the start and end of the function.  A programming language is a language and language is supposed to make sense in regards to its intended purpose.

- Mike

Jan Mercl

unread,
Sep 21, 2013, 12:51:06 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 6:42 PM, Michael Daconta
<michael...@gmail.com> wrote:
> Hi Andrey,
>
> It may be a minor thing to many, I just don't think it should be something
> that is enforced because the language should not care where I place the
> curly braces.
> No one who has responded has answered the question on whether this issue is
> caused by the automatic insertion of semi-colon behavior or if the language
> spec actually requires K&R. If it is the former, it is a bug. If it is the
> latter, then the language designers are enforcing an arbitrary decision
> which I maintain is poor design.
>
> So, instead of saying, you shouldn't prefer one form over the other. The
> real question is "why are you making me choose?"
> Explain that,

Go is not making anyone choose. With Go there's no choice of style.
The gofmt'ed source style is the only accepted one.

Anecdotal but true: ~99% of code I write by hand is gofmt'ed before
even using go fmt on it.

-j

Michael Daconta

unread,
Sep 21, 2013, 12:51:56 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
I would not know but I don't believe Python chose to be in the C-language family to leverage the knowledge of C programmers as Go has done...

Rémy Oudompheng

unread,
Sep 21, 2013, 12:53:48 PM9/21/13
to Michael Daconta, golang-nuts
2013/9/21 Michael Daconta <michael...@gmail.com>:
> Ok, I understand your sentiment but you have not answered the question
> beyond the assertion that "it doesn't matter."
>
> It doesn't matter - to you. Maybe this is a philosophical point - why would
> a language design enforce a feature that has no bearing on the compilation
> of the code?
>
> From a "language-legality standpoint" -
>
> why is
> func main() {
> }
>
> legal and
> func main()
> {
> // tbd
> }
>
> not legal? Both declare a function and both assert the start and end of the
> function. A programming language is a language and language is supposed to
> make sense in regards to its intended purpose.

No this is incorrect. The second form is:

A external function declaration without body:

func main()

and a block of code :

{
// tbd
}

It is illegal to have orphan blocks of code at top level.

Rémy.

Michael Daconta

unread,
Sep 21, 2013, 12:58:40 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Remy,

I was not precise enough - instead of language spec - I should have said language grammar.
Semi-colon insertion is a convenience and cannot be part of the language grammar.  Certainly semi-colons are part of the language grammar.
I will look at the language grammar in detail - my gut feeling is that this program:

package main;

import "fmt";

func main() 
{
fmt.Printf("hello, world!\n");
}

Is legal according to the language grammar.  *If* that is true, we should not even be debating this ... the current behavior of the compiler would then be considered a bug.

- Mike

Rémy Oudompheng

unread,
Sep 21, 2013, 1:03:48 PM9/21/13
to Michael Daconta, golang-nuts
On 2013/9/21 Michael Daconta <michael...@gmail.com> wrote:
> Hi Remy,
>
> I was not precise enough - instead of language spec - I should have said
> language grammar.
> Semi-colon insertion is a convenience and cannot be part of the language
> grammar. Certainly semi-colons are part of the language grammar.
> I will look at the language grammar in detail - my gut feeling is that this
> program:
>
> package main;
>
> import "fmt";
>
> func main()
> {
> fmt.Printf("hello, world!\n");
> }
>
> Is legal according to the language grammar. *If* that is true, we should
> not even be debating this ... the current behavior of the compiler would
> then be considered a bug.

It is not legal. Semicolon insertion is part of the language grammar.
You can think of the formal grammar element "Semicolon" as
corresponding to either of the following elements of source code:
- the character ';'
- the character '\n' (line feed) preceded by: an alphanumeric
character or identifier character or an operator, or ), ], }

Semicolon insertion is not allowed to be "implementation-specific".

Rémy.

Michael Daconta

unread,
Sep 21, 2013, 1:04:37 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
So, you are asserting that a newline somehow "detaches" the block of code from the function declaration that precedes it (sans semi-colon)...
So, given that why not extend your metaphor to say that "one space between the function name and start of the code block is legal but 2 spaces is illegal"... why favor one whitespace character over another?

Sorry, that does not make sense to me,

- Mike

Jan Mercl

unread,
Sep 21, 2013, 1:04:57 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 6:58 PM, Michael Daconta
<michael...@gmail.com> wrote:
> Hi Remy,
>
> I was not precise enough - instead of language spec - I should have said
> language grammar.
> Semi-colon insertion is a convenience and cannot be part of the language
> grammar.


No one ever said that semicolon insertion is part of the language
grammar. Actually, semicolon injection is part of the language
specification.

> Certainly semi-colons are part of the language grammar.

Correct.

> I will look at the language grammar in detail - my gut feeling is that this
> program:
>
> package main;
>
> import "fmt";
>
> func main()

The above line is seen, according to the specs, by the compiler as:

func main();

> {
> fmt.Printf("hello, world!\n");
> }


> Is legal according to the language grammar.

Yes and it means declaring a function implemented in assembler or C.

C specification, in one of its translation phases, prescribes
replacing certaing parts of the source code by other character
sequencies. In _later_ phases, the transformed text is checked against
the language grammar.

Go does just the same.

-j

Jan Mercl

unread,
Sep 21, 2013, 1:06:49 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 7:04 PM, Michael Daconta
<michael...@gmail.com> wrote:
> So, you are asserting that a newline

It's not the newline. It's the semicolon, which is inserted there
according to the really simple semi injection rules.

> somehow "detaches" the block of code
> from the function declaration that precedes it (sans semi-colon)...
> So, given that why not extend your metaphor to say that "one space between
> the function name and start of the code block is legal but 2 spaces is
> illegal"... why favor one whitespace character over another?

-j

Rémy Oudompheng

unread,
Sep 21, 2013, 1:07:47 PM9/21/13
to Michael Daconta, golang-nuts
2013/9/21 Michael Daconta <michael...@gmail.com>:
> So, you are asserting that a newline somehow "detaches" the block of code
> from the function declaration that precedes it (sans semi-colon)...
> So, given that why not extend your metaphor to say that "one space between
> the function name and start of the code block is legal but 2 spaces is
> illegal"... why favor one whitespace character over another?

There is a very large number of languages where newlines have a
specific meaning, and where 2 spaces are equivalent to one space. Go
is simply one of these.

Rémy.

Michael Daconta

unread,
Sep 21, 2013, 1:17:16 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Jan,

Ok, now we are getting to the crux of the issue - what does the language grammar say.


On Saturday, September 21, 2013 1:04:57 PM UTC-4, Jan Mercl wrote:
On Sat, Sep 21, 2013 at 6:58 PM, Michael Daconta
<michael...@gmail.com> wrote:
> Hi Remy,
>
> I was not precise enough - instead of language spec - I should have said
> language grammar.
> Semi-colon insertion is a convenience and cannot be part of the language
> grammar.


No one ever said that semicolon insertion is part of the language
grammar. Actually, semicolon injection is part of the language
specification.


As an aside, is there really a difference between semicolon insertion and semicolon injection?  End-result seems the same...
 
> Certainly semi-colons are part of the language grammar.

Correct.

> I will look at the language grammar in detail - my gut feeling is that this
> program:
>
> package main;
>
> import "fmt";
>
> func main()

The above line is seen, according to the specs, by the compiler as:

func main();

> {
> fmt.Printf("hello, world!\n");
> }



Ok, so you are saying that the pre-processor is inserting (or injecting) a semi-colon after the main() declaration which is not my intent.
How is that not a bug in the pre-processor?

The language spec says: "White space, formed from spaces (U+0020), horizontal tabs (U+0009), carriage returns (U+000D), and newlines (U+000A), is ignored except as it separates tokens that would otherwise combine into a single token. Also, a newline or end of file may trigger the insertion of asemicolon. While breaking the input into tokens, the next token is the longest sequence of characters that form a valid token."

White space ... is ignored and a newline *may* (not MUST) trigger the insertion (not injection) of a semi-colon.

Thus, from a language standpoint - this should ignore the newline which is whitespace.
The behavior of the pre-processor is wrong.

- Mike

Michael Daconta

unread,
Sep 21, 2013, 1:19:51 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Jan,

That is the point I am trying to make (unsuccessfully)...

The "really simple" semicolon injection rules are violating the language grammar by incorrectly inserting a semi-colon where one was not required, nor requested.
A program taking incorrect action is usually considered a bug.

- Mike

Jan Mercl

unread,
Sep 21, 2013, 1:21:56 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 7:17 PM, Michael Daconta
<michael...@gmail.com> wrote:
> Ok, so you are saying that the pre-processor is inserting (or injecting) a
> semi-colon after the main() declaration which is not my intent.
> How is that not a bug in the pre-processor?
>
> The language spec says: "White space, formed from spaces (U+0020),
> horizontal tabs (U+0009), carriage returns (U+000D), and newlines (U+000A),
> is ignored except as it separates tokens that would otherwise combine into a
> single token. Also, a newline or end of file may trigger the insertion of
> asemicolon. While breaking the input into tokens, the next token is the
> longest sequence of characters that form a valid token."

You cannot read only the part of the specs you like. As a rule of
thumb, you cannot pull any arbitraty part of the specification and use
it for reasoning while pretending the rest of the specs do not exists.
They do exist:

""""
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 "}".

""""

-j

Michael Daconta

unread,
Sep 21, 2013, 1:22:40 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Remy,

Well, you are not reading the same language grammar that I am.

The grammar says whitespace is ignored.

So, it appears this whole issue is because when they changed go to allow semi-colons to be optional, they implemented a simple semi-colon insertion rule that enforced K&R style which is not enforced in the language grammar.  Given the language grammar is the final word on the "legality" of the language.  The incorrect semi-colon insertion is a bug.

- Mike

Jan Mercl

unread,
Sep 21, 2013, 1:25:41 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 7:19 PM, Michael Daconta
<michael...@gmail.com> wrote:
> That is the point I am trying to make (unsuccessfully)...
>
> The "really simple" semicolon injection rules are violating the language
> grammar by incorrectly inserting a semi-colon where one was not required,
> nor requested.
> A program taking incorrect action is usually considered a bug.

If the semicolons are injected where _specified_ - it cannot be
"incorrectly" by definition.

Consider a legal Go program:

package main

func f()

func main() {}

----

Seen by the compiler it is:

package main;

func f();

func main() {};

So now, if the semicolon after 'func f()' would _not_ be inserted, it
would become an invalid program. IOW, your argument is not valid as
well.

-j

Jan Mercl

unread,
Sep 21, 2013, 1:29:27 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 7:22 PM, Michael Daconta
<michael...@gmail.com> wrote:
> Hi Remy,
>
> Well, you are not reading the same language grammar that I am.
>
> The grammar says whitespace is ignored.
>
> So, it appears this whole issue is because when they changed go to allow
> semi-colons to be optional, they implemented a simple semi-colon insertion
> rule that enforced K&R style which is not enforced in the language grammar.
> Given the language grammar is the final word on the "legality" of the
> language. The incorrect semi-colon insertion is a bug.

The reasoning above is broken by ignoring some parts of the specs
while using other parts of it as if they exist in vacuum.

-j

Michael Daconta

unread,
Sep 21, 2013, 1:31:54 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Jan,

Yes, I agree with you that you cannot take one part of the spec in isolation to prove a point.
I do see the part of the spec you are referring to regarding the semi-colons; however, that verbiage is not really the grammar.  The Grammar is the EBNF notation.
I am looking through that now to see what it says relating to the whitespace between a function declaration and its code block...

- Mike

Michael Daconta

unread,
Sep 21, 2013, 1:35:34 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Jan,

I tried your "legal go program" and this is what go run says:

C:\Projects\gosrc>go run test.go
# command-line-arguments
.\test.go:3: missing function body

So, according to go - it is not a legal program.

I don't know what point you were trying to make,

- Mike

Andy Balholm

unread,
Sep 21, 2013, 1:39:24 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
On Saturday, September 21, 2013 10:31:54 AM UTC-7, Michael Daconta wrote:
I do see the part of the spec you are referring to regarding the semi-colons; however, that verbiage is not really the grammar.  The Grammar is the EBNF notation.

Many languages have a grammar that can't be perfectly expressed in EBNF. Additional restrictions are specified alongside the EBNF in English. The combination of the EBNF and those restrictions is the real grammar of the language. 

Jan Mercl

unread,
Sep 21, 2013, 1:40:10 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 7:35 PM, Michael Daconta
<michael...@gmail.com> wrote:
> Hi Jan,
>
> I tried your "legal go program" and this is what go run says:
>
> C:\Projects\gosrc>go run test.go
> # command-line-arguments
> .\test.go:3: missing function body
>
> So, according to go - it is not a legal program.
>
> I don't know what point you were trying to make,

The point is that the program is legal. The code compiles sucessfully:

jnml@r630 ~/src/tmp $ cat main.go
package main

func f()

func main() {}
jnml@r630 ~/src/tmp $ go tool 6g main.go && echo "legal"
legal
jnml@r630 ~/src/tmp $

----

It's only the linker phase which fails.

-j

Rémy Oudompheng

unread,
Sep 21, 2013, 1:44:11 PM9/21/13
to Michael Daconta, golang-nuts
On 2013/9/21 Michael Daconta <michael...@gmail.com> wrote:
> Hi Jan,
>
> Yes, I agree with you that you cannot take one part of the spec in isolation
> to prove a point.
> I do see the part of the spec you are referring to regarding the
> semi-colons; however, that verbiage is not really the grammar. The Grammar
> is the EBNF notation.

The specification does not contain a complete formal EBNF grammar of Go.
The grammar of Go is specified by the verbiage.

I thought the specification contained a warning that the EBNF snippet
do not form a true Go grammar but I can't find it back.

Rémy.

Rémy Oudompheng

unread,
Sep 21, 2013, 1:45:37 PM9/21/13
to Michael Daconta, golang-nuts
On 2013/9/21 Michael Daconta <michael...@gmail.com> wrote:
> Hi Jan,
>
> I tried your "legal go program" and this is what go run says:
>
> C:\Projects\gosrc>go run test.go
> # command-line-arguments
> .\test.go:3: missing function body
>
> So, according to go - it is not a legal program.
>
> I don't know what point you were trying to make,

It is a legal Go program. However, from the toolchain point of view,
it cannot form a proper executable because the function body must be
supplied by a C or assembly source file, which is not the case in your
example. When no C or assembly files are present, the external
function declarations are rejected to avoid user-unfriendly errors
that may happen later.

Rémy.

Michael Daconta

unread,
Sep 21, 2013, 1:48:10 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Jan,

No, not really.

Ok, so here is the EBNF grammar:

Function     = Signature FunctionBody
The whitespace between tokens is ignored until the next token is reached...
The fact that the pre-processor is being over-zealous and inserting a semi-colon (termination symbol) between the function declaration and the function body is an error of the pre-processor, not the program.

- Mike

Rémy Oudompheng

unread,
Sep 21, 2013, 1:50:40 PM9/21/13
to Michael Daconta, golang-nuts
On 2013/9/21 Michael Daconta <michael...@gmail.com> wrote:
> Hi Jan,
>
> No, not really.
>
> Ok, so here is the EBNF grammar:
>
> Function = Signature FunctionBody
>
> The whitespace between tokens is ignored until the next token is reached...
> The fact that the pre-processor is being over-zealous and inserting a
> semi-colon (termination symbol) between the function declaration and the
> function body is an error of the pre-processor, not the program.

It's not an error, the specification says there is a semicolon here.
There is no point in continuing this conversation until you accept
that this is *specified* and that *it is the grammar*.

People might make a distinction between semi-colon insertion and the
grammar, but that's just adding confusion. The grammar says that some
newlines are semicolons. Period.

Rémy.

Jan Mercl

unread,
Sep 21, 2013, 1:51:26 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 7:48 PM, Michael Daconta
<michael...@gmail.com> wrote:
> Hi Jan,
>
> No, not really.
>
> Ok, so here is the EBNF grammar:
>
> Function = Signature FunctionBody

And few lines lower one sees:

""""
A function declaration may omit the body. Such a declaration provides
the signature for a function implemented outside Go, such as an
assembly routine.
""""

Not a single programming language can be defined using only grammar.
You must attach semantics of the grammar clauses in the surrounding
text. Which says that the function body may be ommited.

> The whitespace between tokens is ignored until the next token is reached...
> The fact that the pre-processor is being over-zealous

Working as specified cannot be, by definition, being over-zealous ;-)

-j

Michael Daconta

unread,
Sep 21, 2013, 1:52:52 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Remy,

Yes, looking at the documentation page I do not see a full formal EBNF grammar in an appendix - which is surprising.  
By including the many snippets of grammar, they should have included the complete grammar as an appendix.

But on examination of even what they have there - the productions on function declarations are clear.

This is an error in the Go pre-processor for assuming it is ok to add a semi-colon when the function body clearly exists on the next line.
Trying to determine proper behavior based on the presence or lack thereof of whitespace is a slippery slope.  If you want to go that route, you might as well adopt the python style which eliminates the braces all together in favor of newlines and indentation.

- Mike

Jan Mercl

unread,
Sep 21, 2013, 1:54:27 PM9/21/13
to Rémy Oudompheng, Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 7:50 PM, Rémy Oudompheng
<remyoud...@gmail.com> wrote:
> It's not an error, the specification says there is a semicolon here.

Correct. Specifically here: http://golang.org/ref/spec#TopLevelDecl

""""
TopLevelDecl = Declaration | FunctionDecl | MethodDecl .
""""

and here: http://golang.org/ref/spec#Source_file_organization

""""
SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
""""

It's the semi after 'TopLevelDecl'.

-j

Michael Daconta

unread,
Sep 21, 2013, 1:57:49 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Remy,

Ok but the spec is not the EBNF grammar.  But I do agree that it is in the spec on what the behavior for semi-colon insertion is (in this case, after the closing paren)..

- Mike

Rémy Oudompheng

unread,
Sep 21, 2013, 1:57:48 PM9/21/13
to Michael Daconta, golang-nuts
On 2013/9/21 Michael Daconta <michael...@gmail.com> wrote:
> Hi Remy,
>
> Yes, looking at the documentation page I do not see a full formal EBNF
> grammar in an appendix - which is surprising.
> By including the many snippets of grammar, they should have included the
> complete grammar as an appendix.
>
> But on examination of even what they have there - the productions on
> function declarations are clear.

No they are not clear. The EBNF grammar obtained by combinating the
snippets is ambigous and imcomplete.
There is *no* complete EBNF grammar of Go in the specification, and
this is intentional. The specification is written for humans with the
goal of being still unambiguous. It is not written for compilers.

> This is an error in the Go pre-processor for assuming it is ok to add a
> semi-colon when the function body clearly exists on the next line.
> Trying to determine proper behavior based on the presence or lack thereof of
> whitespace is a slippery slope. If you want to go that route, you might as
> well adopt the python style which eliminates the braces all together in
> favor of newlines and indentation.

Indentation-based blocks were suggested multiple times and there are
clear arguments against it. Go aims at best programmer productivity.
The chosen compromises look fine to me for that goal.

Rémy.

Michael Daconta

unread,
Sep 21, 2013, 2:02:11 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Ok, Jan - we can end this discussion but it is not the grammar.  The grammar is fine.
it is the behavior of the semi-colon insertion.  I get the trade off - in order to allow semi-colons to be optional, they made a decision to do the semi-colon insertion.
The spec does specify how they do the semi-colon insertion.

So, while the grammar does not account for this, the verbiage in the spec does.  So, you can argue that the spec is the spec and the pre-processor conforms to the specs rules around semi-colon insertion.  That behavior forces the K&R style but the K&R style is not actually formally in the EBNF grammar.

As I said - I get the trade off even if I don't like it,

- Mike

Jan Mercl

unread,
Sep 21, 2013, 2:05:44 PM9/21/13
to Michael Daconta, golang-nuts
On Sat, Sep 21, 2013 at 7:52 PM, Michael Daconta
<michael...@gmail.com> wrote:
> Yes, looking at the documentation page I do not see a full formal EBNF
> grammar in an appendix - which is surprising.

jnml@r630 ~ $ go get code.google.com/p/godeit/ebnflint2
jnml@r630 ~ $ go get github.com/cznic/ebnf2y
jnml@r630 ~ $ ebnflint2 -start SourceFile ~/go/doc/go_spec.html |
ebnf2y -oe /dev/stdout -o /dev/null
add_op = "+"
| "-"
| "|"
| "^" .
assign_op = [ add_op | mul_op ] "=" .
big_u_value = "\\" "U" hex_digit hex_digit hex_digit hex_digit
hex_digit hex_digit hex_digit hex_digit .
binary_op = "||"
| "&&"
| rel_op
| add_op
| mul_op .
byte_value = octal_byte_value | hex_byte_value .
decimal_digit = "0" … "9" .
decimal_lit = ( "1" … "9" ) { decimal_digit } .
decimals = decimal_digit { decimal_digit } .
escaped_char = "\\" (
"a"
| "b"
| "f"
| "n"
| "r"
| "t"
| "v"
| "\\"
| "'"
| "\""
) .
exponent = ( "e" | "E" ) [ "+" | "-" ] decimals .
float_lit = decimals "." [ decimals ] [ exponent ]
| decimals exponent
| "." decimals [ exponent ] .
hex_byte_value = "\\" "x" hex_digit hex_digit .
hex_digit = "0" … "9"
| "A" … "F"
| "a" … "f" .
hex_lit = "0" ( "x" | "X" ) hex_digit { hex_digit } .
identifier = letter { letter | unicode_digit } .
imaginary_lit = ( decimals | float_lit ) "i" .
int_lit = decimal_lit
| octal_lit
| hex_lit .
interpreted_string_lit = "\"" { unicode_value | byte_value } "\"" .
letter = unicode_letter | "_" .
little_u_value = "\\" "u" hex_digit hex_digit hex_digit hex_digit .
mul_op = "*"
| "/"
| "%"
| "<<"
| ">>"
| "&"
| "&^" .
newline = .
octal_byte_value = "\\" octal_digit octal_digit octal_digit .
octal_digit = "0" … "7" .
octal_lit = "0" { octal_digit } .
raw_string_lit = "`" { unicode_char | newline } "`" .
rel_op = "=="
| "!="
| "<"
| "<="
| ">"
| ">=" .
rune_lit = "'" ( unicode_value | byte_value ) "'" .
string_lit = raw_string_lit | interpreted_string_lit .
unary_op = "+"
| "-"
| "!"
| "^"
| "*"
| "&"
| "<-" .
unicode_char = .
unicode_digit = .
unicode_letter = .
unicode_value = unicode_char
| little_u_value
| big_u_value
| escaped_char .

AnonymousField = [ "*" ] TypeName .
ArgumentList = ExpressionList [ "..." ] .
ArrayLength = Expression .
ArrayType = "[" ArrayLength "]" ElementType .
Assignment = ExpressionList assign_op ExpressionList .
BaseType = Type .
BaseTypeName = identifier .
BasicLit = int_lit
| float_lit
| imaginary_lit
| rune_lit
| string_lit .
Block = "{" StatementList "}" .
BreakStmt = "break" [ Label ] .
BuiltinArgs = Type [ "," ArgumentList ]
| ArgumentList .
BuiltinCall = identifier "(" [ BuiltinArgs [ "," ] ] ")" .
Call = "(" [ ArgumentList [ "," ] ] ")" .
Channel = Expression .
ChannelType = (
"chan" [ "<-" ]
| "<-" "chan"
) ElementType .
CommCase = "case" ( SendStmt | RecvStmt )
| "default" .
CommClause = CommCase ":" StatementList .
CompositeLit = LiteralType LiteralValue .
Condition = Expression .
ConstDecl = "const" (
ConstSpec
| "(" { ConstSpec ";" } ")"
) .
ConstSpec = IdentifierList [
[ Type ] "=" ExpressionList
] .
ContinueStmt = "continue" [ Label ] .
Conversion = Type "(" Expression [ "," ] ")" .
Declaration = ConstDecl
| TypeDecl
| VarDecl .
DeferStmt = "defer" Expression .
Element = [ Key ":" ] Value .
ElementIndex = Expression .
ElementList = Element { "," Element } .
ElementType = Type .
EmptyStmt = .
ExprCaseClause = ExprSwitchCase ":" StatementList .
ExprSwitchCase = "case" ExpressionList
| "default" .
ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" {
ExprCaseClause } "}" .
Expression = UnaryExpr
| Expression binary_op UnaryExpr .
ExpressionList = Expression { "," Expression } .
ExpressionStmt = Expression .
FallthroughStmt = "fallthrough" .
FieldDecl = (
IdentifierList Type
| AnonymousField
) [ Tag ] .
FieldName = identifier .
ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
ForStmt = "for" [
Condition
| ForClause
| RangeClause
] Block .
Function = Signature FunctionBody .
FunctionBody = Block .
FunctionDecl = "func" FunctionName ( Function | Signature ) .
FunctionLit = "func" Function .
FunctionName = identifier .
FunctionType = "func" Signature .
GoStmt = "go" Expression .
GotoStmt = "goto" Label .
IdentifierList = identifier { "," identifier } .
IfStmt = "if" [ SimpleStmt ";" ] Expression Block [
"else" ( IfStmt | Block )
] .
ImportDecl = "import" (
ImportSpec
| "(" { ImportSpec ";" } ")"
) .
ImportPath = string_lit .
ImportSpec = [ "." | PackageName ] ImportPath .
IncDecStmt = Expression ( "++" | "--" ) .
Index = "[" Expression "]" .
InitStmt = SimpleStmt .
InterfaceType = "interface" "{" { MethodSpec ";" } "}" .
InterfaceTypeName = TypeName .
Key = FieldName | ElementIndex .
KeyType = Type .
Label = identifier .
LabeledStmt = Label ":" Statement .
Literal = BasicLit
| CompositeLit
| FunctionLit .
LiteralType = StructType
| ArrayType
| "[" "..." "]" ElementType
| SliceType
| MapType
| TypeName .
LiteralValue = "{" [ ElementList [ "," ] ] "}" .
MapType = "map" "[" KeyType "]" ElementType .
MethodDecl = "func" Receiver MethodName ( Function | Signature ) .
MethodExpr = ReceiverType "." MethodName .
MethodName = identifier .
MethodSpec = MethodName Signature
| InterfaceTypeName .
Operand = Literal
| OperandName
| MethodExpr
| "(" Expression ")" .
OperandName = identifier | QualifiedIdent .
PackageClause = "package" PackageName .
PackageName = identifier .
ParameterDecl = [ IdentifierList ] [ "..." ] Type .
ParameterList = ParameterDecl { "," ParameterDecl } .
Parameters = "(" [ ParameterList [ "," ] ] ")" .
PointerType = "*" BaseType .
PostStmt = SimpleStmt .
PrimaryExpr = Operand
| Conversion
| BuiltinCall
| PrimaryExpr Selector
| PrimaryExpr Index
| PrimaryExpr Slice
| PrimaryExpr TypeAssertion
| PrimaryExpr Call .
QualifiedIdent = PackageName "." identifier .
RangeClause = (
ExpressionList "="
| IdentifierList ":="
) "range" Expression .
Receiver = "(" [ identifier ] [ "*" ] BaseTypeName ")" .
ReceiverType = TypeName
| "(" "*" TypeName ")"
| "(" ReceiverType ")" .
RecvExpr = Expression .
RecvStmt = [
ExpressionList "="
| IdentifierList ":="
] RecvExpr .
Result = Parameters | Type .
ReturnStmt = "return" [ ExpressionList ] .
SelectStmt = "select" "{" { CommClause } "}" .
Selector = "." identifier .
SendStmt = Channel "<-" Expression .
ShortVarDecl = IdentifierList ":=" ExpressionList .
Signature = Parameters [ Result ] .
SimpleStmt = EmptyStmt
| ExpressionStmt
| SendStmt
| IncDecStmt
| Assignment
| ShortVarDecl .
Slice = "[" (
[ Expression ] ":" [ Expression ]
)
| (
[ Expression ] ":" Expression ":" Expression
) "]" .
SliceType = "[" "]" ElementType .
SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
Statement = Declaration
| LabeledStmt
| SimpleStmt
| GoStmt
| ReturnStmt
| BreakStmt
| ContinueStmt
| GotoStmt
| FallthroughStmt
| Block
| IfStmt
| SwitchStmt
| SelectStmt
| ForStmt
| DeferStmt .
StatementList = { Statement ";" } .
StructType = "struct" "{" { FieldDecl ";" } "}" .
SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
Tag = string_lit .
TopLevelDecl = Declaration
| FunctionDecl
| MethodDecl .
Type = TypeName
| TypeLit
| "(" Type ")" .
TypeAssertion = "." "(" Type ")" .
TypeCaseClause = TypeSwitchCase ":" StatementList .
TypeDecl = "type" (
TypeSpec
| "(" { TypeSpec ";" } ")"
) .
TypeList = Type { "," Type } .
TypeLit = ArrayType
| StructType
| PointerType
| FunctionType
| InterfaceType
| SliceType
| MapType
| ChannelType .
TypeName = identifier | QualifiedIdent .
TypeSpec = identifier Type .
TypeSwitchCase = "case" TypeList
| "default" .
TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
TypeSwitchStmt = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" {
TypeCaseClause } "}" .
UnaryExpr = PrimaryExpr
| unary_op UnaryExpr .
Value = Expression | LiteralValue .
VarDecl = "var" (
VarSpec
| "(" { VarSpec ";" } ")"
) .
VarSpec = IdentifierList (
Type [ "=" ExpressionList ]
| "=" ExpressionList
) .
jnml@r630 ~ $

-j

Thomas Bushnell, BSG

unread,
Sep 21, 2013, 2:06:19 PM9/21/13
to Michael Daconta, golang-nuts

The parsing rules for go, which mandate the implicit semicolons, require that the second here is a syntax error. I get that you don't like the language's grammar, but I don't think you understand that to grammar is perfectly clear, and does in fact prohibit one of these.

On Sep 21, 2013 9:51 AM, "Michael Daconta" <michael...@gmail.com> wrote:
Ok, I understand your sentiment but you have not answered the question beyond the assertion that "it doesn't matter."

It doesn't matter - to you.  Maybe this is a philosophical point - why would a language design enforce a feature that has no bearing on the compilation of the code?

From a "language-legality standpoint" - 

why is 
func main() { 

legal and 
func main() 
{
 // tbd

not legal?  Both declare a function and both assert the start and end of the function.  A programming language is a language and language is supposed to make sense in regards to its intended purpose.

- Mike

On Saturday, September 21, 2013 10:51:16 AM UTC-4, Volker Dobler wrote:
Am Samstag, 21. September 2013 15:50:31 UTC+2 schrieb Michael Daconta:

Adoption is not a single event... it is an ongoing continuum.
This absolutely will hurt adoption because it is foolish enforcement with no good reason.  It is "because I said so" enforcement.  It may not matter to many people, but it will to some.
So, how much adoption is hurt by it is irrelevant, the fact remains that it will hurt adoption which is why I consider it a poor design choice.


And blue bike sheds won't help adoption of bike-to-work
for those who insist on red sheds...

Just stay away if you really cannot cope with Go.

V.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Michael Daconta

unread,
Sep 21, 2013, 2:13:24 PM9/21/13
to golan...@googlegroups.com, Rémy Oudompheng, Michael Daconta
Hi Jan and Remy,

I do not believe it is the semicolon after the TopLevelDecl in the grammar that is the issue.  Yes, a semi-colon is required but that is not the point here.
The point is that the semi-colon insertion rule states that at the end-of-a-line you insert a semi-colon based on certain conditions specified in the language spec.
In this case, since the line ends with a closing paren ')' and not a '{' the pre-processor is incorrectly assuming (yes, I know it is in the spec but in terms of my intent it is incorrect) that I want to create a Top-level decl instead of starting the function body.  

In accordance with the EBNF it would not have made that assumption, but in accordance with the semi-colon insertion rules it can make that assumption.

Thus, lies the trade off between optional semi-colons (supported by simple semi-colon insertion rules) and K&R,

- Mike

Michael Daconta

unread,
Sep 21, 2013, 2:17:41 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Excellent, but there is nothing in this grammar that states that this program is illegal:
package main;

import "fmt";

func main() 
{
fmt.Printf("hello, world!\n");
}

It is fully and completely the result of the go pre-processor executing the semi-colon insertion rules and assuming I want to have func main() be a Top-level decl with an empty body.
Which is an incorrect assumption,

- Mike

Michael Daconta

unread,
Sep 21, 2013, 2:19:45 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Thomas,

It is not the grammar that states that.  It is the semi-colon insertion rules in the spec.  Technically, that is not a formal part of the language (to the compiler) but a pre-processing step.

- Mike

Antoine Grondin

unread,
Sep 21, 2013, 2:39:23 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Given so much energy in fighting the good cause of An Allman Style For All, why not focus that energy on modifying Go or gofmt so that it would accept the style.  You've argued that it's an error, others said it's not.  I think your best course of action would now be to prove that it is an error with a proof of concept that fixes said error.

The mailing list could then carry on discussing other things while this hypothesis is being investigated by those interested.

roger peppe

unread,
Sep 21, 2013, 2:43:33 PM9/21/13
to Michael Daconta, golang-nuts
On 21 September 2013 19:19, Michael Daconta <michael...@gmail.com> wrote:
> It is not the grammar that states that. It is the semi-colon insertion
> rules in the spec. Technically, that is not a formal part of the language
> (to the compiler) but a pre-processing step.

Which technicality dictates that? The compiler does all the processing from
bytes all the way to manipulation of abstract-syntax trees.
Why is semi-colon-insertion not a "formal" part of the language
to the compiler? The insertion may happen at tokenization time,
but that doesn't make it any less a part of the language.

You've also missed a point that Rob Pike made earlier - if/when
someone makes an interactive command line interpreter for Go,
the current syntax means that the interpreter can know immediately
when a line is ready to be executed - it doesn't have to look ahead.
This is a very nice property to have.

Thomas Bushnell, BSG

unread,
Sep 21, 2013, 3:04:23 PM9/21/13
to Michael Daconta, golang-nuts

What is this preprocessor of which you speak? There is no preprocessor.

I think this may be at the root of your confusion. In C, there is conventionally a preprocessor which has nothing to do with the specification of the language itself. You seem to be thinking that go is similar, and that some preprocessor is doing the semicolon insertion as some kind of convenience feature. But that is not correct. Go has no preprocessor, and the semicolon insertion is as integral to the language as the use of range in for statements or the specification of "chan" as a reserved word.

Thomas

--

Thomas Bushnell, BSG

unread,
Sep 21, 2013, 3:05:10 PM9/21/13
to Michael Daconta, golang-nuts

You are incorrect. It is a formal part of to language, and there is no preprocessor in Go.

Michael Daconta

unread,
Sep 21, 2013, 3:16:00 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Antoine,

That is an excellent suggestion.  I did not know it was open source but I assume it is based on your message... so I will check out this option.

Regards,

- Mike

Michael Daconta

unread,
Sep 21, 2013, 3:22:48 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Rog,

The language is specified by the EBNF grammar and nothing else in terms of what the compiler should accept as a "legal" program.
I think a simple example of that is that the language requires semi-colons but these have been made optional by defining the semi-colon insertion rules.

You are correct, I must have missed that point by Rob.  I will go back in the posts... but I don't see that Go is really geared at an interactive command line interpreter.
Seems like a red-herring to me,

- Mike

Thomas Bushnell, BSG

unread,
Sep 21, 2013, 3:23:54 PM9/21/13
to Michael Daconta, golang-nuts

You're incorrect. It is specified by the entire text of the specification, and not by some subset you've chosen.

--

Michael Daconta

unread,
Sep 21, 2013, 3:28:15 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Hi Thomas,

Whether it is called a pre-processor or not does not matter, the step that does semi-colon insertion is absolutely a pre-processing step to make the source code conform to the EBNF grammar.

Well, we may have to disagree on the semi-colon insertion - here is a simple proof.  If I insert the semi-colons myself then I don't need the semi-colon insertion step.  Thus, semi-colon insertion is NOT integral to the language, semi-colons are.

- Mike

Rémy Oudompheng

unread,
Sep 21, 2013, 3:36:38 PM9/21/13
to Michael Daconta, golang-nuts
On 2013/9/21 Michael Daconta <michael...@gmail.com>:
> Hi Thomas,
>
> Whether it is called a pre-processor or not does not matter, the step that
> does semi-colon insertion is absolutely a pre-processing step to make the
> source code conform to the EBNF grammar.
>
> Well, we may have to disagree on the semi-colon insertion - here is a simple
> proof. If I insert the semi-colons myself then I don't need the semi-colon
> insertion step. Thus, semi-colon insertion is NOT integral to the language,
> semi-colons are.
>

If I replace all constants by their value, I don't need constant
declarations. So constant declarations are not part of the language?

Rémy.

quarnster

unread,
Sep 21, 2013, 3:54:58 PM9/21/13
to golan...@googlegroups.com
The bracket style turned me off for a long time, and then I actually tried using the language and fell in love with the philosophy that drives it. Just read http://commandcenter.blogspot.se/2012/06/less-is-exponentially-more.html and if you don't understand why less is exponentially more, Go isn't for you and hopefully never will be. And by that I mean that I hope everyone working on the language sticks to this philosophy of less being exponentially more.

/f

Michael Daconta

unread,
Sep 21, 2013, 3:59:52 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Depends on what the EBNF says...

Michael Daconta

unread,
Sep 21, 2013, 4:00:15 PM9/21/13
to golan...@googlegroups.com
Thanks!  I'll check it out...

Andy Balholm

unread,
Sep 21, 2013, 4:04:14 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
On Saturday, September 21, 2013 12:22:48 PM UTC-7, Michael Daconta wrote:
The language is specified by the EBNF grammar and nothing else in terms of what the compiler should accept as a "legal" program.
 
No, this program conforms to the grammar but is not legal:

package main

func main() {
    fmt.Printf("hello, world")
}


Rémy Oudompheng

unread,
Sep 21, 2013, 4:08:52 PM9/21/13
to Michael Daconta, golang-nuts
On 2013/9/21 Michael Daconta <michael...@gmail.com> wrote:
> Depends on what the EBNF says...
>

There is no such thing in the Go specification. Stop thinking it's true.

Rémy.

Dan Kortschak

unread,
Sep 21, 2013, 5:00:51 PM9/21/13
to Michael Daconta, golan...@googlegroups.com, Michael Daconta
Just for a minute disregarding the rest if the argumentation here, if you were to accept the style you are proposing, how would you differentiate foo() and foo() {}?

al...@lx.lc

unread,
Sep 21, 2013, 5:59:50 PM9/21/13
to golan...@googlegroups.com
Quite a long discussion here I see.  It seems strange to me that you mention Java, as Sun's original style guide - and I believe even Oracle's now - recommends bracing this way.  K&R/1tbs is the right way, don't try and fight it :).  
In seriousness, I understand where you come from.  In fact, I probably would myself not have picked up Go if Allman style were enforced, as I find it disgusting.  This is not to insult you or anyone else, as it appears you feel similarly about Go's style.  
That said, I really come to appreciate Go's style and more importantly that gofmt exists and is used.  There is no having to readjust because someone uses some strange style when looking at source.  In the end, it make it much easier to quickly scan source when you know exactly what the style is, rather than having to guess on even a function level basis in some languages.  
There are other things I'd imagine people don't like, such as types coming after variable names, and people have made this complaint before.  In the end, I'm happy that the language designers hold their ground on such debates, as it guides a consistency and gives me confidence that I won't have to relearn the language or be caught offguard when browsing source in a year from now.  
As you've suggested, if you must have Allman style, why not just write a quick translation script?  Just messing around in 5 mins, this might be a good start -  echo "sed -e ':a;N;\$!ba;s/\n\s*{/ {/g' \$1.allman > \$1.go && go build \$1.go" > build-allman.sh
 
Regards,
Alex

On Friday, September 20, 2013 9:58:03 PM UTC-4, Michael Daconta wrote:
Hi Go fans,

I frankly was shocked to learn that a program like:

package main;

import "fmt";

func main() 
{
fmt.Printf("hello, world!\n");
}

... is currently illegal in go with the error:

# command-line-arguments
.\hello.go:6: syntax error: unexpected semicolon or newline before {

From reading the newsgroups, I see that this is illegal due to the automatic insertion of semi-colons; however, what if I added my own semi-colons into the code as in the above.  From a language perspective the above should be legal Go code.  To me, it seems like a hack for convenience (making semi-colons optional) has forced a K&R style on everyone.
For me, this is a show-stopper.  Frankly, I am surprised that Google would enforce a coding style (K&R) while saying that "go fmt" frees you from worrying about divergent coding styles.  Sorry, google - you cannot have it both ways.  Unless the Allman-style code above is illegal in the language (which makes no sense from a language semantics point of view) - get the compiler to accept it. Period.

Yes, I know I can write my own translator - but why?  Heck, I can just stick with Java...

C'mon Google, when trying to pitch a new language, you can (and should) do better than this...

- Mike

luz...@gmail.com

unread,
Sep 21, 2013, 7:39:59 PM9/21/13
to golan...@googlegroups.com
List of brace styles preferred by designers or official documentation of curly braces programming languages:

B inventor Thompson: hanging braces
C inventors (K&R): hanging braces (exception: function braces)
AWK inventors in The AWK Programming Language book: hanging braces
C++ inventor Stroustrup: hanging braces (exception: function braces)
Apple's Objective-C documentation: hanging braces
Perl man perlstyle: hanging braces
Java Code Conventions: hanging braces
Brendan Eich and MDN JavaScript reference: hanging braces
CSS in W3C Recommendation: hanging braces
PHP Manual: hanging braces
ActionScript: Allman style
C#: Allman style
The D Style: Allman style
Scala Style Guide: hanging braces
Groovy documentation: hanging braces
Go: hanging braces
Rust developers and documentation: hanging braces
Opa language documentation: hanging braces
Kotlin: hanging braces
Ceylon: hanging braces
TypeScript: hanging braces

Hanging braces are the clear winner. ActionScript, C# and D are the exception. Even C# designer Hejlsberg is doing hanging braces now with TypeScript.

TR NS

unread,
Sep 21, 2013, 7:44:06 PM9/21/13
to golan...@googlegroups.com, Michael Daconta
Simple answer: the convention saves us from most of this nonsense: http://en.wikipedia.org/wiki/Indent_style

Hell, I'd be happier if they got rid of the brackets altogether and just used `end` keyword. But I guess they wanted to make C coders feel at home (though I am not sure why, since the word is C coders aren't all that interested in Go).

za...@zachlatta.com

unread,
Sep 21, 2013, 8:04:03 PM9/21/13
to golan...@googlegroups.com
This is a relatively naive argument against Go. Any style is as good as any other, as long as it's consistent. Go's fmt tool was created to avoid meaningless disputes like this.

Michael Daconta

unread,
Sep 21, 2013, 8:27:29 PM9/21/13
to golan...@googlegroups.com
Hi Alex, 

Good points and you are right about Java - though I always used Allman style when programming in Java and in C.
Preferences aside, I did take the opportunity to cobble together a Go program that uses text/scanner to reformat the code.
Not pretty but it was fun even playing with Go a little bit to get a basic program working.

I may improve it over time and continue to pick up Go little by little...

Regards,

- Mike

Michael Daconta

unread,
Sep 21, 2013, 8:32:39 PM9/21/13
to golan...@googlegroups.com, luz...@gmail.com
Interesting list and conclusion.  I wonder if that is just the power of inertia and the popularity of the original C Programming Language book (http://en.wikipedia.org/wiki/The_C_Programming_Language).  Anyway, you are correct - K&R is the most popular.  :(   

Regards,

- Mike

Jesse McNelis

unread,
Sep 21, 2013, 9:37:19 PM9/21/13
to Michael Daconta, golang-nuts
On Sun, Sep 22, 2013 at 10:27 AM, Michael Daconta <michael...@gmail.com> wrote:
Good points and you are right about Java - though I always used Allman style when programming in Java and in C.
Preferences aside, I did take the opportunity to cobble together a Go program that uses text/scanner to reformat the code.
Not pretty but it was fun even playing with Go a little bit to get a basic program working.

I may improve it over time and continue to pick up Go little by little...

The bracing style isn't arbitrary. It allows a line of Go code to be known to be complete or not without looking ahead to the next line. This isn't all that important for a compiler, but if you're typing on to a REPL it allows the REPL to know if you've completed the statement and want it executed or if you're going to continue it on the next line.
A REPL is yet to exist for Go, but Haskell is a great example of a language that failed to account for a REPL during syntax design and now has to have different additional syntax to coop with it.

The other style things you'll soon notice are:
* Leaving parentheses off 'if' and 'for' statements
if a < b {}

* The order of type and name of function parameters. 
func a(b int, c float64)

* That the semicolon insertion rules require you to put commas, operators, etc. at the end of the line and not the start
eg.
a = a+
     b
instead of 
a = a
     + b

* That gofmt uses tabs for indentation and spaces for alignment (this combination irritates a number of people)
* That leaving semicolons off the end of statements in Go will increase the likelihood of you doing it in other languages and make those instances far more irritating. 

But the best part is that once you teach yourself to write and read Go code in gofmt style you'll never have to learn it in a different style again. Every Go project you're involved with will have the same formatting style.


--
=====================
http://jessta.id.au

chris dollin

unread,
Sep 22, 2013, 4:25:34 AM9/22/13
to Michael Daconta, golang-nuts
On 21 September 2013 20:22, Michael Daconta <michael...@gmail.com> wrote:
Hi Rog,

The language is specified by the EBNF grammar and nothing else in terms of what the compiler should accept as a "legal" program.

This is untrue. The language is specified by the language
spec, all of it, both the formal notations (the EBNF fragments)
and the informal (but technical) English that, eg, defines the
semicolon insertion rules.

Why would this ever not be the case?

Chris

--
Chris "allusive" Dollin

Stefano Casillo

unread,
Sep 22, 2013, 5:26:09 AM9/22/13
to golan...@googlegroups.com
On Saturday, September 21, 2013 3:58:03 AM UTC+2, Michael Daconta wrote:
For me, this is a show-stopper.

nah.. don't make such a big deal about it.

I have been using the:

whatever()
{

}

Style since I started programming (mostly C++) eons ago and still do in my C++ code.. so I understand where you come from.  However you'll quickly get used to switch your brain to Go style whenever you are using Go, and the more Go code you read, the more you'll understand how important was their decision to go for a uniform style.

Really, that is a show stopper for you and inverted type declarations arent? come on

 

Michael Daconta

unread,
Sep 22, 2013, 11:52:24 AM9/22/13
to golan...@googlegroups.com, Michael Daconta, ehog....@googlemail.com
Hi Chris,

We may have to disagree here because the EBNF is what specifies how you lex and parse the language formally.
The verbal part of the spec usually just explains the EBNF, clarifies its decisions, etc.

At least that is my understanding from my compiler class and lexer/parser experience,

- Mike

Michael Daconta

unread,
Sep 22, 2013, 11:57:51 AM9/22/13
to golan...@googlegroups.com
Hi Stefano,

Good point on the inverted type declarations!
Yes, this could be just an initial reaction to something that was unexpected and something I felt should not be enforced (please let's not rehash all the benefits of enforcement as I get it)...

Thanks for the gentle reminder about temperance,

- Mike

Jan Mercl

unread,
Sep 22, 2013, 12:02:35 PM9/22/13
to Michael Daconta, golang-nuts, chris dollin
On Sun, Sep 22, 2013 at 5:52 PM, Michael Daconta
<michael...@gmail.com> wrote:
> We may have to disagree here because the EBNF is what specifies how you lex
> and parse the language formally.
> The verbal part of the spec usually just explains the EBNF, clarifies its
> decisions, etc.
>
> At least that is my understanding from my compiler class and lexer/parser
> experience,

The language specification prescribes how the source code is
transformed _before_ the parser sees it. Conceptually it's no
different than what the C99 standard prescribes about trigraphs and/or
#directives. All of the mentioned is specified to happened before
parsing the _transformed_ source code text.

To be more precise, parser sees tokens, not the source code anymore,
so what's actually inserted/injected is the semicolon token - as a
transformation of the '\n' character in the input text at the
tokenizer level (not really important detail). And again, it's the
same concept as in C trigraphs and/or #directives regardless of the
different transformation rules.

Actually, the specs (of any language) are free to prescribe any
transformation whatsoever and at any level. EBNF per se is never
enough to specify a PL - it lacks any definition of the semantics.

-j
It is loading more messages.
This conversation is locked
You cannot reply and perform actions on locked conversations.
0 new messages