go/parser changes

38 views
Skip to first unread message

Robert Griesemer

unread,
Dec 11, 2009, 6:49:24 PM12/11/09
to golang-nuts, golang-dev
If you are not writing Go code that imports the go/parser package, you can ignore this e-mail.

The latest version of the go/parser package (revision eb649506b8, CL 175046) is now accepting the new syntax, with semicolons inserted automatically. The old parser remains available as exp/parser, the package name is oldParser.

All code in the repository is accepted by both the old and the new parser for now, but if you are relying explicitly on the old syntax you may want to change your import from

    import "go/parser"

to

    import parser "exp/parser"

(the rename is required because exp/parser's package name is oldParser so that it can be imported at the same time as go/parser).

If you have Go files that are not correct for the new syntax, use the latest version of gofmt to rewrite them accordingly.

- gri

Russ Cox

unread,
Dec 11, 2009, 7:06:04 PM12/11/09
to Robert Griesemer, golang-nuts
(This mail and Robert's apply to the current Mercurial tip;
if you stay at release you won't be subjected to this churn.)

On a related note, the gc compilers now implement the
new semicolon proposal. If you find that you have a
program that is no longer accepted, you can convert it
into a syntax acceptable to both old and new compilers
using

gofmt -w *.go

after running all.bash to build the new gofmt.

If you want to convert your code to the new semicolon-free
style, you can use:

gofmt -oldprinter=false -w *.go

Please do experiment, but be ready for churn
until we tag a new release. We might refine the proposal
as we gain experience with the new rules.

Russ

peterGo

unread,
Dec 12, 2009, 10:49:11 AM12/12/09
to golang-nuts
The new rules (e7f3b2a4d933 tip) are too fragile.

For perfectly legal syntax, they output error message: 3: syntax error
near main.

package main
func main()
{
return
}

gofmt reformats to:

package main

func main() { return }

which does compile

Peter

Eden Li

unread,
Dec 12, 2009, 1:53:42 PM12/12/09
to peterGo, golang-nuts
On Sat, Dec 12, 2009 at 7:49 AM, peterGo <go.pe...@gmail.com> wrote:
> The new rules (e7f3b2a4d933 tip) are too fragile.
>
> For perfectly legal syntax, they output error message: 3: syntax error
> near main.
>
> package main
> func main()
> {
>        return
> }
>
> gofmt reformats to:
>
> package main
>
> func main()     { return }
>
> which does compile

`else` or `else if` on their own lines also fail to compile:

$ cat > else.go <<EOF
> package main
>
> func main() {
> if true {
> println("foo")
> }
> else if false {
> println("bar")
> }
> else {
> println("baz")
> }
> }
> EOF
$ 6g else.go
else.go:7: syntax error near else
else.go:10: syntax error near else

gofmt fixes this as well, but this would probably cause huge headaches
for newcomers to Go that are used to different bracing styles.

Russ Cox

unread,
Dec 12, 2009, 3:01:33 PM12/12/09
to peterGo, golang-nuts
On Sat, Dec 12, 2009 at 07:49, peterGo <go.pe...@gmail.com> wrote:
> The new rules (e7f3b2a4d933 tip) are too fragile.

They're simply different from the old rules,
and there is a trivial update path, as pointed
out elsewhere (gofmt -w *.go).

Russ

smosher

unread,
Dec 12, 2009, 3:57:04 PM12/12/09
to golang-nuts
On Dec 12, 1:53 pm, Eden Li <eden...@gmail.com> wrote:
This is much worse than I'd expected. In the other thread I simply
mentioned that I didn't like it and left it at that because not
needing semicolons is a nice result. But now, the language seems to
have become very whitespace sensitive in a lot of places with terse
syntax errors. While I don't ever write code in the above styles,
sometimes I do write:

if ...
else ...

if they are convenient one-liners. I really should have picked up on
this earlier.

I know there's technical reasons for all this but the argument that
"it's easier to compile" seems to have been abused. It also seems
absurd that, unless has been promoted to the role of "preprocessor",
gofmt can make sense of the above without any special flags while the
compiler cannot. It's no longer purely a style tool. (I'm not against
this, but if it is to be the case can we _please_ have a means to
invoke it from the compiler?)

Sverre Rabbelier

unread,
Dec 12, 2009, 4:31:20 PM12/12/09
to smosher, golang-nuts
Heya,

On Sat, Dec 12, 2009 at 21:57, smosher <dark.n...@gmail.com> wrote:
> It's no longer purely a style tool. (I'm not against
> this, but if it is to be the case can we _please_ have a means to
> invoke it from the compiler?)

Now there's an interesting thought, one could even imagine the
compiler rejecting the code if it does not match 'gofmt's output to
ensure that everybody uses the gofmt style.

--
Cheers,

Sverre Rabbelier

Russ Cox

unread,
Dec 12, 2009, 4:40:45 PM12/12/09
to smosher, golang-nuts
> It also seems
> absurd that, unless has been promoted to the role of "preprocessor",
> gofmt can make sense of the above without any special flags while the
> compiler cannot.

Gofmt can only make sense of the old code because
it has two different parsers compiled into the binary,
one for the old syntax and one for the new syntax.
(It has two different printers too.)

Right now when you run gofmt, it assumes
-oldparser=true and -oldprinter=true, and the
printer for the old syntax uses the intersection
of the two (i.e. semicolons in many places that
the new syntax doesn't require, and no newlines
in some places that the old syntax allows).
That is, right now, by default, gofmt converts old
code into code that works in both worlds; again
by default, it does not generate and cannot read
new (semicolon-free) code.

To officially switch to the new syntax, we'll change
the flag defaults. If you've been using gofmt to format
your code already, you won't have a problem -- the
compiler will accept your code, and running it through
gofmt again will throw away a lot of unnecessary
semicolons. If you haven't been using gofmt, you'll
have to convert your program manually or run
gofmt -oldparser=true to read and convert the old
syntax.

This is all just to help the transition. Once a few releases
have gone by using the new syntax, we'll retire the
old parsing and printing code and take the flags out of gofmt.
At that point the old syntax will be just a memory.

Letting gofmt run the transition means that neither
gccgo nor 6g needs the complexity of two different
parsers.

Russ

s mosher

unread,
Dec 12, 2009, 5:26:20 PM12/12/09
to r...@golang.org, golang-nuts
On Sat, Dec 12, 2009 at 4:40 PM, Russ Cox <r...@golang.org> wrote:
> This is all just to help the transition.  Once a few releases
> have gone by using the new syntax, we'll retire the
> old parsing and printing code and take the flags out of gofmt.
> At that point the old syntax will be just a memory.

That certainly clears up the absurdities. It still doesn't really work
for me because while this is apparently a feature for the programmer,
the rule is designed instead for the compiler. Maybe I'm alone, but
the execution of this particular feature makes me think "what?--why?"
The answer seems to be "well if we only do a half-decent job of it
(from the user's perspective) then the parser code is nicer."

That's just my take, and I know a lot of people don't mind or care,
and that the language is by-and-for Google (at this point anyway.)
It's not going to break my heart if things don't go my way, but since
Go is a language that has a chance of satisfying many of my needs in a
modern way I feel I should be giving honest feedback.

Russ Cox

unread,
Dec 12, 2009, 6:49:55 PM12/12/09
to s mosher, golang-nuts
> That certainly clears up the absurdities. It still doesn't really work
> for me because while this is apparently a feature for the programmer,
> the rule is designed instead for the compiler.

I don't think that's fair - our primary goal is to make the
language more pleasant for people, not for the compiler.

> Maybe I'm alone, but
> the execution of this particular feature makes me think "what?--why?"
> The answer seems to be "well if we only do a half-decent job of it
> (from the user's perspective) then the parser code is nicer."

I'm not sure what you're referring to. The only time I remember
mentioning the compiler in the other semicolon thread was in response
to someone saying that the new rules were more complicated
than the old ones. The compiler and go/parser changes are a
counter-example to that claim. And the only time it's been
mentioned in this thread was to explain that because of gofmt,
it doesn't need to maintain parsers for two different languages
and a flag to select which one you're using.

But again, we're more concerned with how the language looks
and feels to write than we are with the compiler implementation.

Since the canonical format (the output of gofmt) doesn't need
a special case for else, I personally don't think it's worth adding
to the language specification complexity that won't be used;
others may disagree.

> It's not going to break my heart if things don't go my way, but since
> Go is a language that has a chance of satisfying many of my needs in a
> modern way I feel I should be giving honest feedback.

We appreciate the feedback.

Russ

Bob Cunningham

unread,
Dec 12, 2009, 7:13:55 PM12/12/09
to r...@golang.org, Robert Griesemer, golang-nuts
I tried both of the above gofmt calls on the following code (tuple.go):

package main

import "fmt"

func tuple(args...) (...) { return args }

func main() {
a := tuple(1, "abc", 3.14);
fmt.Printf("%v %v %v\n", a);
}

Note the lack of a space in the middle of: "args...".

gofmt provides this error: "tuple.go:5:22: expected type, found '...'

Yet the code compiles and runs fine (with and without the space) via: 8g tuple.go; 8l tuple.8; 8.out
after which it prints: 1 abc 3.14

Compiler (or spec) bug when the space is missing?


-BobC

Russ Cox

unread,
Dec 12, 2009, 7:32:27 PM12/12/09
to Bob Cunningham, golang-nuts
>  func tuple(args...) (...) { return args }

This isn't a valid program according to the spec.
The fact that 6g/8g accept it is the bug (sorry).

The real way to write this function is

func tuple(args ...) interface{} { return args }

Russ

s mosher

unread,
Dec 12, 2009, 9:03:37 PM12/12/09
to r...@golang.org, golang-nuts
On Sat, Dec 12, 2009 at 6:49 PM, Russ Cox <r...@golang.org> wrote:
>> That certainly clears up the absurdities. It still doesn't really work
>> for me because while this is apparently a feature for the programmer,
>> the rule is designed instead for the compiler.
>
> I don't think that's fair - our primary goal is to make the
> language more pleasant for people, not for the compiler.
>
>> Maybe I'm alone, but
>> the execution of this particular feature makes me think "what?--why?"
>> The answer seems to be "well if we only do a half-decent job of it
>> (from the user's perspective) then the parser code is nicer."
>
> I'm not sure what you're referring to. The only time I remember
> mentioning the compiler in the other semicolon thread was in response
> to someone saying that the new rules were more complicated
> than the old ones. The compiler and go/parser changes are a
> counter-example to that claim. And the only time it's been
> mentioned in this thread was to explain that because of gofmt,
> it doesn't need to maintain parsers for two different languages
> and a flag to select which one you're using.

My issue is that the programmer will see something that he understands
immediately as a single statement broken up onto two lines that the
compiler will (mis?)interpret as a statement on one line followed by a
syntax error on the next. If the parser looked ahead a little (I
understand just how disgusting this is) it could be made to reconcile
this case. It's not a good solution, but that's partly why I said "I
don't like it" in the first thread.

I am partly referring to that particular exchange about simplicity of
the rules. If the compiler uses every complete statement it finds by
the end of a line it makes for great simplicity as a rule. This is
great for the parser, but I find it isn't so great for me.

I'm not sure whether it is fair or even that it should be. My gut
tells me that a lot of people coming from outside will have the same
reaction I have had, but many (most?) can be expected to take a pass
on the language without providing feedback. So I think it's fair to
make the statement even if the statement itself isn't fair. This is
why I'm bringing it up.

> But again, we're more concerned with how the language looks
> and feels to write than we are with the compiler implementation.
>
> Since the canonical format (the output of gofmt) doesn't need
> a special case for else, I personally don't think it's worth adding
> to the language specification complexity that won't be used;
> others may disagree.

I'm not sure that gofmt always has the right thing to say. I'll go so
far as to say that 99.5% of the time code should be unambiguous at the
end of a line (i.e. complying with the new rule), in the sense that
this change shouldn't matter at all for those cases. On the other
hand, about once in 200 lines I'll write an if-else combo in the style
above, or format some math in such a way that Go will now reject, and
I'll probably even be baffled by the syntax error at first despite
knowing the rule.

I think I'm saying that context makes up for a lot of what constitutes
"clear style" and constraining the style too much is frustrating and
perhaps not always clear. When the notion of using a backslash at line
endings for continued lines was brought up I didn't want to support it
(too ugly) but I'm starting to look in that direction. Initially it
wasn't at all an issue for me that gofmt would sometimes render format
much differently than I would like to see for the purposes of clarity,
but now that things have become stricter in that regard it is
literally cramping my style.

>> It's not going to break my heart if things don't go my way, but since
>> Go is a language that has a chance of satisfying many of my needs in a
>> modern way I feel I should be giving honest feedback.
>
> We appreciate the feedback.
>
> Russ

I'm glad to hear it. I have found the Go team pays a lot of attention
to the community. It's really something else.

Many of the problems brought up on the list are hard to solve, and my
objections here are particularly hard to resolve completely (in fact I
would even advise against it, unless you come up with something really
clever) while still moving forward with this feature. I don't need to
be convinced of anything, it's more important to me that you're aware
of what I consider to be an issue. I'm certainly not saying "you're
doing it wrong," but perhaps I am saying "there's no such thing as
'perfect'."

SnakE

unread,
Dec 13, 2009, 11:30:06 AM12/13/09
to r...@golang.org, s mosher, golang-nuts
2009/12/13 Russ Cox <r...@golang.org>

> That certainly clears up the absurdities. It still doesn't really work
> for me because while this is apparently a feature for the programmer,
> the rule is designed instead for the compiler.

I don't think that's fair - our primary goal is to make the
language more pleasant for people, not for the compiler.

I supported the new syntax initially, but now I'm not so sure.  The problem is, this new syntax invalidates some of the commonly used formatting styles used in C, C++, Java, C# etc.  It's not about having a style anymore, it's about forbidding some which is a whole different story.

Sergio Luis O. B. Correia

unread,
Dec 13, 2009, 12:21:43 PM12/13/09
to SnakE, r...@golang.org, s mosher, golang-nuts
I am thinking exactly like you. To be honest, I didn't see the
"different" semicolon go initially proposed to be such a problem to
deserve a rethink. It's different, yeah, but people get used to it
after writing some code. This change in it forbidding some styles, as
you mentioned, is way more unpleasant - to me, at least.

Evan Shaw

unread,
Dec 13, 2009, 2:29:02 PM12/13/09
to Sergio Luis O. B. Correia, r...@golang.org, golang-nuts
I agree with those who are concerned about the new syntax preventing certain formatting styles. I totally understand the need for a standard way of formatting Go, but going so far as to disallow other styles doesn't seem like a win to me. It seems more like something that will confuse and annoy newcomers.

- Evan

Russ Cox

unread,
Dec 13, 2009, 2:36:55 PM12/13/09
to SnakE, golang-nuts
> I supported the new syntax initially, but now I'm not so sure.  The problem
> is, this new syntax invalidates some of the commonly used formatting styles
> used in C, C++, Java, C# etc.

But Go isn't these languages. You can't write

for (i=0; i<10; i++) {
}

either, but that doesn't seem to bother anyone.

> It's different, yeah, but people get used to it
> after writing some code.

Exactly.

Russ

SnakE

unread,
Dec 14, 2009, 4:17:20 PM12/14/09
to r...@golang.org, golang-nuts
2009/12/13 Russ Cox <r...@golang.org>

> I supported the new syntax initially, but now I'm not so sure.  The problem
> is, this new syntax invalidates some of the commonly used formatting styles
> used in C, C++, Java, C# etc.

But Go isn't these languages.  You can't write

  for (i=0; i<10; i++) {
  }

either, but that doesn't seem to bother anyone.

True, but the more you differ from C the more you have to explain to newcomers.  And syntax matters, it's your own words.  Currently the end-of-statement rules in Go are much closer to TCL than to C.  But in TCL they're very easy to explain:

End-of-line ends a statement except when it's between brackets.

That's it.  I hope I didn't forget anything.  This rule doesn't allow you to break after '+', but OTOH allows to break however you please within the round brackets:

x := (
    a
    +
    b
    -
    c
    )

is valid.

Just my ¢2.  I'm not really sure if it's worth changing again.

Russ Cox

unread,
Dec 14, 2009, 5:55:27 PM12/14/09
to SnakE, golang-nuts
> End-of-line ends a statement except when it's between brackets.

https://groups.google.com/group/golang-nuts/msg/db8018422f085592

SnakE

unread,
Dec 14, 2009, 6:39:17 PM12/14/09
to r...@golang.org, golang-nuts
2009/12/15 Russ Cox <r...@golang.org>

> End-of-line ends a statement except when it's between brackets.

https://groups.google.com/group/golang-nuts/msg/db8018422f085592

This actually raises another language design question: why imports are grouped with round brackets but separated with semicolons?  It surprises me every time I write a grouped import.  First I'm remembering how I should group them then how to separate them.  Granted I didn't write a lot of Go code but still.  I always try to use commas there because it resembles parameter list that much.  If imports were grouped by curly brackets It would be only natural to separate elements with semicolons.  Same goes for const and var declarations.

If you were going for this change, you would have to:

1.  Group imports, vars, and consts with curly brackets
2.  Group arguments of composite literals by round brackets

Then everything becomes terribly simple: newlines in the global scope and inside curly brackets imply semicolons; otherwise they don't.

Um, I suppose it's ¢4 already.

jimmy frasche

unread,
Dec 14, 2009, 7:17:23 PM12/14/09
to r...@golang.org, SnakE, golang-nuts
On Mon, Dec 14, 2009 at 2:55 PM, Russ Cox <r...@golang.org> wrote:
>> End-of-line ends a statement except when it's between brackets.
>
> https://groups.google.com/group/golang-nuts/msg/db8018422f085592
>

I understand this argument. The naive change would require that
instead of having this extra rule in your lexer/scanner:

If newline in non-top-level then insert semicolon

you just need:

if there's a ( or a [ then inc counter
if there's a ) or a ] then dec counter
if newline then {
if counter = 0 then insert semicolon
if counter < 0 then ERROR
if counter > 0 then this-is-the-same-logical-line-so-keep-on-going
}

This would make it possible to write arbitrarly long logical lines and
to call functions with (too) many paramaters easily.

However, the lexer/scanner can't distinguish between the {} in
array/struct/et al literals and those of code blocks. so () and [] get
a pass but {} gets screwed.

So to sanely support
a := (
b
+
d
)
then there are only two options change the syntax so that {} are only
used for code blocks or change the syntax so that it is entirely
layout based. While I am much in favor of the layout = structure in
general in general, I don't see it happening.

I'd have to look at the BNF of Go again to see if it would be possible
to only use {} for code.

It would be weird to type something like the below but it seems reasonable:
type (
point struct (
x, y, z int
)
)

Or []int(1, 2, 3, 4).
But my first guess is that such a change would create ambiguitues with
struct literals.

Jeffrey

unread,
Dec 14, 2009, 10:14:53 PM12/14/09
to golang-nuts
Because every global declaration begins with a keyword, and because
global declarations don't nest, why are parentheses needed in factored
import and declaration blocks at all? What ambiguity would arise if
they were dropped? Isn't it sufficient to note that the next token is
import/const/type/var/func to determine that the factored import or
declaration block has ended? True, parsing is more complicated, but
it's simpler for the user.

Now, there would be problems in parsing such factored statements
inside functions without the parentheses. Is that the reason they are
included in all cases -- for orthogonality?

I, too, would like to see the "Python" rule of "don't infer end of
statement if inside parentheses," but I don't see how to get it to
work.

- Jeffrey

Robert Griesemer

unread,
Dec 14, 2009, 11:21:22 PM12/14/09
to Jeffrey, golang-nuts
On Mon, Dec 14, 2009 at 7:14 PM, Jeffrey <merri...@gmail.com> wrote:
Because every global declaration begins with a keyword, and because
global declarations don't nest, why are parentheses needed in factored
import and declaration blocks at all?  What ambiguity would arise if
they were dropped?  Isn't it sufficient to note that the next token is
import/const/type/var/func to determine that the factored import or

yes.
 
declaration block has ended?  True, parsing is more complicated, but
it's simpler for the user.

I don't think parsing would be more complicated at all if one could use the same notation inside functions.

(As an aside - contrary to the belief that seems to have established itself - we are not making syntax decisions primarily to make the compiler writer's job easier; otherwise we would use Lisp notation or some such... :-) 

Now, there would be problems in parsing such factored statements
inside functions without the parentheses.  Is that the reason they are
included in all cases -- for orthogonality?

yes. 

- gri

Michael Hoisie

unread,
Dec 15, 2009, 2:42:59 AM12/15/09
to golang-nuts
After syncing a lot of my code wouldn't compile.

I noticed that my if-else statements weren't being accepted by the new
parser because I was writing:

if {
}
else {
}

It took a while to figure out the error - that the else needed to be
moved one line above. I can't really see why this was changed -- and
in general, I would highly advise against enforcing bracket styles on
a programmer.

On Dec 14, 8:21 pm, Robert Griesemer <g...@google.com> wrote:

Marcin 'Qrczak' Kowalczyk

unread,
Dec 15, 2009, 2:57:09 AM12/15/09
to jimmy frasche, r...@golang.org, SnakE, golang-nuts
2009/12/15 jimmy frasche <soapbo...@gmail.com>:

>   if there's a ( or a [ then inc counter
>   if there's a  ) or a ] then dec counter
>   if newline then {
>        if counter = 0 then insert semicolon
>        if counter < 0 then ERROR
>        if counter > 0 then this-is-the-same-logical-line-so-keep-on-going
>   }

This does not work correctly in function literals living inside
parens, where I would expect semicolons between statements to be
implicit.

--
Marcin Kowalczyk

Russ Cox

unread,
Dec 15, 2009, 3:33:24 AM12/15/09
to Michael Hoisie, golang-nuts
gofmt -w *.go

jimmy frasche

unread,
Dec 15, 2009, 12:26:10 PM12/15/09
to Marcin 'Qrczak' Kowalczyk, r...@golang.org, SnakE, golang-nuts
On Mon, Dec 14, 2009 at 11:57 PM, Marcin 'Qrczak' Kowalczyk
<qrcz...@gmail.com> wrote:
> This does not work correctly in function literals living inside
> parens, where I would expect semicolons between statements to be
> implicit.

I was demonstrating that it is a harder problem than people think.

eadfrith

unread,
Dec 15, 2009, 12:44:49 PM12/15/09
to golang-nuts


On Dec 14, 11:42 pm, Michael Hoisie <hoi...@gmail.com> wrote:

> It took a while to figure out the error - that the else needed to be
> moved one line above. I can't really see why this was changed -- and
> in general, I would highly advise against enforcing bracket styles on
> a programmer.

I completely agree. The bugs have started to come in on this:

http://code.google.com/p/go/issues/detail?id=430&

http://code.google.com/p/go/issues/detail?id=427&

They'll probably be told to run gofmt -w *.go

Either make gofmt part of the language/compiler or let developers
choose which bracketing/code layout style they wish to use.

jimmy frasche

unread,
Dec 15, 2009, 12:49:53 PM12/15/09
to eadfrith, golang-nuts
> Either make gofmt part of the language/compiler or let developers
> choose which bracketing/code layout style they wish to use.


Maybe the easiest, but less satisfying, solution is to have a switch
on the compiler to not auto-insert semicolons?

Antoine Chavasse

unread,
Dec 15, 2009, 1:26:34 PM12/15/09
to eadfrith, golang-nuts
On Tue, Dec 15, 2009 at 6:44 PM, eadfrith <eadf...@gmail.com> wrote:
>
>
> I completely agree. The bugs have started to come in on this:
>
> http://code.google.com/p/go/issues/detail?id=430&
>
> http://code.google.com/p/go/issues/detail?id=427&
>
> They'll probably be told to run gofmt -w *.go
>
> Either make gofmt part of the language/compiler or let developers
> choose which bracketing/code layout style they wish to use.

Agreed. The compiler _must_ be flexible with regard to the way the
input is formatted.

One of go's concept is that compilation is lighting fast. If the
compilation process have to include fixing misplaced braces or having
to run through gofmt first, then it doesn't work.

People will say: "when you are used to it you will place the braces at
the right place". But what if I work at a company on C++ code where
the brace standard we use doesn't even compile in go?

I now have to juggle with two different brace standards, both of which
requires me as a human to get it right (at work because we don't have
automatic code formatters and in go because placing the brace at the
wrong place is grammatically incorrect).

Thus the goal of unifying the presentation style actually end up, for
people in a situation like mine, with the opposite result of forcing
me to use two different standards depending if I'm at work or working
on my hobby projects.

Russ Cox

unread,
Dec 15, 2009, 1:55:51 PM12/15/09
to golang-nuts
> But what if I work at a company on C++ code where
> the brace standard we use doesn't even compile in go?

I believe the main reason this is a point of contention is that it
is changing. If we'd shipped Go with parens around the for loop
header and tried to take them out now, many of the arguments
being used here could be recycled to defend the use of parens
in for loops. Please step back and write some code. If the
only thing you notice switching from C++ to Go is that you
can't put a newline in a certain place, you haven't written
enough Go code.

> They'll probably be told to run gofmt -w *.go
>
> Either make gofmt part of the language/compiler or let developers
> choose which bracketing/code layout style they wish to use.

See my post earlier in this thread. The reason gofmt -w works
right now is that it assumes the input is written in the old syntax
and it is careful to write programs that are in the intersection of
the old and new syntax. Once gofmt defaults to the new syntax
for input, the incantation will be gofmt --oldparser -w *.go, and then
after a while we'll toss the old parser. It's a transition tool, not a
magic wand.

Even if you did put gofmt into the compiler as a preprocessor,
it wouldn't solve this problem, unless you decorated each file
with whether it was written in the old or new syntax.

We're very aware of this issue, but one of the reasons to use gofmt
is to give up caring about where the braces are. Let gofmt sort it
out, and use those now-idle neurons to write interesting programs.

Russ

Peter Froehlich

unread,
Dec 15, 2009, 2:20:11 PM12/15/09
to Russ Cox, golang-nuts
Hi all,

On Tue, Dec 15, 2009 at 1:55 PM, Russ Cox <r...@google.com> wrote:
> I believe the main reason this is a point of contention is that it
> is changing.  If we'd shipped Go with parens around the for loop
> [...]
> in for loops.  Please step back and write some code.  If the
> only thing you notice switching from C++ to Go is that you
> can't put a newline in a certain place, you haven't written
> enough Go code.

I am sorry, but it's not changing in a minor way. Taking out parens
around the for loop presumably would have allowed writing it both ways
(since you always have the opening brace of the body to stop the
parser). The problem here is that it's *not* allowing it both ways.
And of course the new else-clause-style is inconsistent with the rest
of the language, but that's a minor point.

When all this started I posted a nasty rant against it and I won't
repeat that. But it has to be said that "write more Go code" is akin
to saying "just get the frick out of here" for a lot of people who
want to play with the language but don't have the time you or I have
to spend on it. If you care about others using the language (and I
assume you do, why else release it?) that's just not very productive.

I'll get back to the core of this as pointed out by many before: You
went from free-form to not free-form. That's a BIG change. And in the
opinion of many it's a bad change, regardless of the nice gofmt tool.
It's C-style syntax, isn't it? Yes, it's quite different, but you made
it look C-like intentionally. How can you expect people to *not*
assume it's free-form when almost every other C-style language is?

Anyways, I am used to it now. One can make peace with a lot of
arbitrary stuff. But nobody has to like it.

Cheers,
Peter
--
Peter H. Froehlich <http://www.cs.jhu.edu/~phf/>
Senior Lecturer | Director, Johns Hopkins Gaming Lab

Russ Cox

unread,
Dec 15, 2009, 2:42:05 PM12/15/09
to Peter Froehlich, golang-nuts
> I am sorry, but it's not changing in a minor way.

Yes, it's a language change. I agree with you that it
would have been easier if we'd made this change a year ago.

> When all this started I posted a nasty rant against it and I won't
> repeat that. But it has to be said that "write more Go code" is akin
> to saying "just get the frick out of here" for a lot of people who
> want to play with the language but don't have the time you or I have
> to spend on it. If you care about others using the language (and I
> assume you do, why else release it?) that's just not very productive.

That's not fair. I do care very much about others using
the language, but I also stand by what I wrote before.
The argument that this will trip up people coming from C++
doesn't fly: Go and C++ are vastly different languages,
and many other things will trip people up besides the
way semicolons work. If you can make the mental switch
to dropping parens around for headers, swapping the
declaration syntax, not declaring methods inside structs,
and so on, you can make the mental switch to typing
} else too.

Russ

Peter Froehlich

unread,
Dec 15, 2009, 2:49:16 PM12/15/09
to r...@golang.org, golang-nuts
On Tue, Dec 15, 2009 at 2:42 PM, Russ Cox <r...@golang.org> wrote:
> The argument that this will trip up people coming from C++
> doesn't fly: Go and C++ are vastly different languages,
> and many other things will trip people up besides the
> way semicolons work.

Agreed. That's why I didn't say C or C++ or whatnot, I said "C-style
syntax" or "C-style language" which is really where the free form
expectation comes from. And that's a deeper issue than where methods
go or which order declarations are made in.

Russ Cox

unread,
Dec 15, 2009, 3:38:08 PM12/15/09
to Peter Froehlich, golang-nuts
> Agreed. That's why I didn't say C or C++ or whatnot, I said "C-style
> syntax" or "C-style language" which is really where the free form
> expectation comes from. And that's a deeper issue than where methods
> go or which order declarations are made in.

Yes, it's a big syntactic change. I understand the
"this is too different from C, because it's now newline sensitive
in many places; you should just require semicolons" argument.
This is a strong, principled argument. We happen to think that
being able to drop the semicolons will make enough of a change
to the feel of the language to justify the difference, but it's a
good argument.

The argument I object to is the one that goes
"this is too different from C, because it's now newline sensitive
in many places; you should have a special exception for just
one of them, left braces, because it will trip up people who
use a different brace convention in C or C++." This is much
weaker argument, because it ignores all the other places
where Go is no longer free-form. It singles out one case
for special treatment.

Russ

eadfrith

unread,
Dec 15, 2009, 4:02:39 PM12/15/09
to golang-nuts


On Dec 15, 12:38 pm, Russ Cox <r...@golang.org> wrote:

> Yes, it's a big syntactic change.  I understand the
> "this is too different from C, because it's now newline sensitive
> in many places; you should just require semicolons" argument.
> This is a strong, principled argument.  We happen to think that
> being able to drop the semicolons will make enough of a change
> to the feel of the language to justify the difference, but it's a
> good argument.

Go is now a programming language with curly brackets that is no longer
a curly-bracket-programming-language:

http://en.wikipedia.org/wiki/Curly_bracket_programming_language

Personally I think the resulting loss of freedom and confusion that
this causes is too high a price to pay for making semi-colons fully
optional.

baldmountain

unread,
Dec 15, 2009, 4:10:26 PM12/15/09
to golang-nuts
On Dec 15, 1:55 pm, Russ Cox <r...@google.com> wrote:
> If the
> only thing you notice switching from C++ to Go is that you
> can't put a newline in a certain place, you haven't written
> enough Go code.


+1

I've written some Go code and I just don't notice the newline issues
people are talking about. The only issue I've had is I keep forgetting
parentheses in the Java if statements I write for my real job.

The alternative to having a standard code format is really nasty. At a
previous job I worked on a version of the Java class libraries. (AWT,
Swing, Collections, etc.) No matter how badly the tabs were screwed up
we could never reformat the code because trying to merge the next drop
from Sun would be a nightmare if we did. If you don't believe me, try
it. Reformat the main branch of the source tree at your current job
into a clean and consistent format and check it in. Then see how long
it is before someone tries to merge in a branch and hunts you down and
kills you...


geoff

eadfrith

unread,
Dec 15, 2009, 4:19:58 PM12/15/09
to golang-nuts


On Dec 15, 1:10 pm, baldmountain <baldmount...@gmail.com> wrote:
> The alternative to having a standard code format is really nasty.

But this is just an argument for adopting a standard code format
within an organization or project - most users of c/c++/java already
do so. Does one style really need to be enforced at the language
level?

SnakE

unread,
Dec 15, 2009, 4:30:45 PM12/15/09
to eadfrith, golang-nuts
2009/12/16 eadfrith <eadf...@gmail.com>

Go is now a programming language with curly brackets that is no longer
a curly-bracket-programming-language:

http://en.wikipedia.org/wiki/Curly_bracket_programming_language

Your statement doesn't follow from the page you link to.  It says that "curly-bracket languages" are those which delimit blocks of code with curly brackets.  It also explicitly mentions BCPL and Pico as CB-languages while they both are white space sensitive, which is also explicitly mentioned.

I wonder why they didn't include TCL in the list.  It matches the definition.

eadfrith

unread,
Dec 15, 2009, 4:42:12 PM12/15/09
to golang-nuts


On Dec 15, 1:30 pm, SnakE <snake.sc...@gmail.com> wrote:

> Your statement doesn't follow from the page you link to.  It says that
> "curly-bracket languages" are those which delimit blocks of code with curly
> brackets.  It also explicitly mentions BCPL and Pico as CB-languages while
> they both are white space sensitive, which is also explicitly mentioned.

I think it's fair to say that C/C++/C#/Java/D/PHP/Javascript are
probably in wider usage than BCPL/Pico? And, to quote from the
article:

"Generally, these languages are considered "free-form languages",
meaning that the compiler considers all whitespace to be the same as
one blank space"

It is in this sense that Go is no longer a CBPL.

atomly

unread,
Dec 15, 2009, 5:11:40 PM12/15/09
to eadfrith, golang-nuts
On Tue, Dec 15, 2009 at 4:19 PM, eadfrith <eadf...@gmail.com> wrote:
> But this is just an argument for adopting a standard code format
> within an organization or project - most users of c/c++/java already
> do so. Does one style really need to be enforced at the language
> level?

Every shop has a "coding standard" that's published on a wiki or an
intranet (or possibly even IDE formatting rules) somewhere and loosely
followed by a few people who care, but I've never worked at a shop
where it's strictly enforced. I always end up being the guy trying to
enforce it and I can really appreciate the idea that the language is
enforcing it instead. We're an Eclipse shop and we install our
standard formatter on everybody's box when they start, but we still
can't even keep the codebase completely consistent.

Sure, the Go syntax isn't my preferred syntax, but I'd much rather
have it be consistent-- I can adapt. Like somebody else in here said,
try going into your day job, opening a bunch of files and running them
through a formatter. I guarantee you'd be getting shouted at by the
next person doing a merge.

--
:: atomly ::

[ ato...@atomly.com : www.atomly.com : http://blog.atomly.com/ ...
[ atomiq records : new york city : +1.917.442.9450 ...
[ e-mail atomly-new...@atomly.com for atomly info and updates ...

Nigel Tao

unread,
Dec 15, 2009, 5:54:36 PM12/15/09
to golang-nuts
2009/12/16 eadfrith <eadf...@gmail.com>:
I would prefer one style to rule them all. I used to work on Gears,
and have dabbled with Chromium, and both projects re-use a number of
third-party libraries. Google's C++ code has a different style than
WebKit's C++ code, which has a different style than Mozilla's C++
code, which has a different style than MFC's C++ code. Making the one
Chromium change may involve writing code in more than one style, even
though it's all C++. It would be easier if I didn't have to worry
about style at all, i.e. if all C++ projects used the same style.

gofmt's style is not my personal idea of perfect style, but it's
consistent, I've grown used to it, and I'm glad it exists.

Antoine Chavasse

unread,
Dec 15, 2009, 7:00:17 PM12/15/09
to r...@golang.org, Peter Froehlich, golang-nuts
I disagree. Most changes from C++ to Go are at the conceptual level,
so we must adapt our way to think, which is okay because you always
need to think when programming anyway.

However, hitting enter - tab - open brace after writing an if
condition is not something people think think about, it's an
tutomatism. This kind of habit is difficult to change and before those
syntactic change, there was no need for people to waste time
retraining the part of their brain that formats the code that they
type. The very purpose of gofmt in the first place is to allow people
not to think about formatting.

You argue that there are better things to think about when writing
code than this and I wholeheartedly agree, which is why I don't want
to be distracted by those issues.
If whenever I switch from writing C++ code to writing go code I need
to stop and fix the positions of those braces all the time because I
get them wrong by habit, then it's going to distract me from the code
itself.

And by the way dropping the parens around for and if conditions are
also something that keeps tripping me up, I'm starting to think that
the idea that semicolons aren't necessary but tolerated to avoid to
annoy people used to insert them should be consistently applied to
other recurrent enough things that have a different syntax than C-like
languages, namely allow people to optionally add parens around if
conditions and in for loops, and allow to put braces on the next line.

Clean it all up in gofmt, that's fine. But tolerate it. It's a bit of
a shame that the same language that features a powerful tool to fix up
formatting also lack so much flexibility in the syntax.
You're creating a bunch of needless annoyances that will make
programmers go back to fix minor formatting issue to please an overly
fussy compiler instead of doing actual work. It's almost a worse
result than if you still mandated semicolons, you've traded an
inconvenience for another.

kq1quick

unread,
Dec 23, 2009, 4:04:04 PM12/23/09
to golang-nuts

I missed this entire discussion and ended up filing issues 453 and
454....
which were closed as WontFix.

And now I must join in the discussion: I believe this was a really bad
idea.

I don't object to syntatical advancements such as eliminating
parentheses around for expressions as Russ has discussed here, but
that's *very* different from imposing the ONE TRUE STYLE. It's also
been said here that Go should be easy for the programmer, and this
change is emphatically not that. As was stated in (many) previous post
(s), this now means wrestling with the compiler over the very type of
pedantism that much of Go was intended to release the C and C++
developer from.

Not only does it prevent my from my own style, it makes the compiler
act in non-orthogonal ways and violates many things already documented
about the language.

IMHO, whitespace is whitespace and designed to be invisible/immaterial
(except in string literals, etc.) in the input language, and this is
reinforced by the language specification:

Tokens

Tokens form the vocabulary of the Go language. There are four
classes: identifiers, keywords, operators and delimiters, and
literals. 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. While breaking the input into tokens, the next token is
the longest sequence of characters that form a valid token.

This is no longer true with the latest change.

Non-orthogonal? Yes:

words := []string { "one", "two", "three" }
words := []string {
"one",
"two",
"three".
}

Note the comma now *required* after "three". The two declarations are
not the same and they require the addition of a *non-whitespace* token
based on whitespace changes.

We also lost adjacent string literal concatenation, an convenient item
that even C supports:

words := "one " "two" " three" ;
words := "one "
"two"
" three"};

Neither of these can even be compiled under the new rules. One of the
major advantages of allowing auto-concatenation of string literals is
to allow multi-line specifications (imagine the string literals were
quite long),

Also non-orthogonal:

type struct s { a int; b int; }
x := s { 3, 5 }
x := s { 3,
5,
}


And what is this?!

if cond
{
do something
}

8g: cond not used

What?! Apparently the { is now *required* to be on the same line as
the if or you get this strange error.

I agree emphatically with all the folks here who think this was a
really bad change. Even those that don't object too strongly still
seem to be dubious. Unfortunately, it's not even fixable by changing
make to run "gofmt X.go | 8g" because of things like the adjacent
string literal concatenation above.

I *really* like Go, and I think it has a lot of useful things. Don't
link it to "religious" issues like formatting... that's not benefiting
anyone. Please enjoy gofmt for your code... don't *require* it for
mine.

If the go developers are unwilling to rollback this change can we
*please* have a command-line option to re-enable the older parsing
functionality?

eadfrith

unread,
Dec 23, 2009, 4:52:02 PM12/23/09
to golang-nuts

The placement of braces is now determined by the grammar of the
language, but whether to use braces on a trailing else is optional:

http://groups.google.com/group/golang-nuts/browse_thread/thread/4bd59c16c8dde565/b6773221d5bcfb32

The only reason for this seems to be that the language designers had a
difference of opinion, so the grammar supports both styles.

Those of us who like to place our braces on new lines are told to
adapt for the sake of consistency, but when the issue matters to the
right people, consistency is compromised.

Rant over.

Reply all
Reply to author
Forward
0 new messages