FAQ
Why aren't newlines just whitespace? I can easily string together a
program all on one line using just spaces and it would build just fine,
there's no required usage of newlines... but there is deliberate
disallowing of them.

I thought it odd that I couldn't put opening { on a newline, and sure,
brevity of not having empty lines with just a { on them sort of makes
sense; although to me makes code less legible... since there's no
requirement to actually indent after a { opening block either.

But that I can't format code with continued lines with the operator leading
into the next line, and have to put it at the end of the prior line is just
unbearable.

for instance...

if( a > 0
b > 0 ) {}
in many simple cases it doesn't matter... but if I have a fairly complex
condition with long meaningful identifiers, then I have to search all the
way to the end of the line to figure out what the operator is.

Similarly...

fmt.Println( "... : ", val1
              , " .... : ", val2

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Volker Dobler at Jun 24, 2015 at 8:10 am

    Am Mittwoch, 24. Juni 2015 10:04:59 UTC+2 schrieb J Decker:
    Why aren't newlines just whitespace? I can easily string together a
    program all on one line using just spaces and it would build just fine,
    there's no required usage of newlines... but there is deliberate
    disallowing of them.

    I thought it odd that I couldn't put opening { on a newline, and sure,
    brevity of not having empty lines with just a { on them sort of makes
    sense; although to me makes code less legible... since there's no
    requirement to actually indent after a { opening block either.

    But that I can't format code with continued lines with the operator
    leading into the next line, and have to put it at the end of the prior line
    is just unbearable.

    for instance...

    if( a > 0
    b > 0 ) {}
    in many simple cases it doesn't matter... but if I have a fairly complex
    condition with long meaningful identifiers, then I have to search all the
    way to the end of the line to figure out what the operator is.

    Similarly...

    fmt.Println( "... : ", val1
    , " .... : ", val2
    Ignoring newlines like spaces would interfere with semicolon insertion.
    One gets used to having logical operator in the preceding lines.

    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • J Decker at Jun 24, 2015 at 8:10 am

    On Wed, Jun 24, 2015 at 1:04 AM, J Decker wrote:

    Why aren't newlines just whitespace? I can easily string together a
    program all on one line using just spaces and it would build just fine,
    there's no required usage of newlines... but there is deliberate
    disallowing of them.

    I thought it odd that I couldn't put opening { on a newline, and sure,
    brevity of not having empty lines with just a { on them sort of makes
    sense; although to me makes code less legible... since there's no
    requirement to actually indent after a { opening block either.

    But that I can't format code with continued lines with the operator
    leading into the next line, and have to put it at the end of the prior line
    is just unbearable.

    for instance...

    if( a > 0
    b > 0 ) {}
    in many simple cases it doesn't matter... but if I have a fairly complex
    condition with long meaningful identifiers, then I have to search all the
    way to the end of the line to figure out what the operator is.

    Similarly...

    fmt.Println( "... : ", val1
    , " .... : ", val2

    (oops accidenatlly hit ctrl-enter)...maybe shift-enter)
                  , " ... : ", val3 );

    Again, in this simple case it doesn't make must difference. Perhaps it's
    just a style choice, and that I modified my preferred linux/windows editor
    to understand leading operators to indent under opening ('s... so
    formatting always lines up properly with proper number of tabs and spaces
    to make the code format correctly no matter what the tab configuration.

    I realize that NOONE does this; it was a long discussion at work to even
    get anyone to consider the merits. Having done this for 10+ years now,
    it's actually very notable when I deal with other's code a lot where they
    have left the operators as traililng.

    Commenting out/replacing portions of if statements also become easier if
    the operator and related expression is on a separate line... otherwise I
    have to comment out part of an expression and the trailing operator on the
    prior line.

    I know; noone cares, and nothing will be done, and it doesn't matter if one
    person doesn't like such a minor aspect... thank you for your time if you
    actually made it this far though.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Andrew Gerrand at Jun 24, 2015 at 9:06 am

    On 24 June 2015 at 18:10, J Decker wrote:

    I know; noone cares, and nothing will be done, and it doesn't matter if
    one person doesn't like such a minor aspect... thank you for your time if
    you actually made it this far though.

    You're welcome. :-)

    Honestly, I can imagine this scheme leading to some pretty gnarly code.

    In the case of Go specifically, it might lead to parsing ambiguities. I
    can't think of any off the top of my head, though.

    (You might already know this, but) An important part of the Go ecosystem is
    the gofmt tool, which makes your Go code look like everyone else's Go code.
    There are big readability benefits here, and it also puts a stop to tedious
    discussions about invisible characters.

    So even if we did use whitespace as a statement separator, we would still
    let gofmt put everything on its own line, so the benefits would be minimal.

    Andrew

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jesse McNelis at Jun 24, 2015 at 8:17 am

    \On Wed, Jun 24, 2015 at 6:04 PM, J Decker wrote:
    Why aren't newlines just whitespace? I can easily string together a program
    all on one line using just spaces and it would build just fine, there's no
    required usage of newlines... but there is deliberate disallowing of them.
    It's a trade off, we trade newlines not being just white space for not
    having to type semicolons at the end of each line.
    It's a good trade off.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • J Decker at Jun 24, 2015 at 2:25 pm

    On Wed, Jun 24, 2015 at 1:17 AM, Jesse McNelis wrote:

    \On Wed, Jun 24, 2015 at 6:04 PM, J Decker wrote:
    Why aren't newlines just whitespace? I can easily string together a program
    all on one line using just spaces and it would build just fine, there's no
    required usage of newlines... but there is deliberate disallowing of
    them.

    It's a trade off, we trade newlines not being just white space for not
    having to type semicolons at the end of each line.
    It's a good trade off.
    Yes but both of these things aren't ; related.. they're bounded by ( and )

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Paul Borman at Jun 24, 2015 at 2:51 pm
    In the formal Go grammar, newlines are actually just white space. The
    lexer, however, treats newlines special in order to let code elide the ;'s
    : https://golang.org/ref/spec#Semicolons

    What does the following code mean?

    a = 1
    b = 2

    Without the lexical rule of adding semicolons, those lines become:

    a = 1 b = 2

    I don't think we want that language. Even if you consider the unclosed (,
    what about:

    foo(bar(), func() { a = 1
    b = 2
    })

    That results in the "a =1 b = 2" issue from above.

    It might be possible that looking ahead to the next token could be used to
    refine when a ; is added or not, but I am not sure of what issues that
    might introduce.

         -Paul
    On Wed, Jun 24, 2015 at 7:25 AM, J Decker wrote:


    On Wed, Jun 24, 2015 at 1:17 AM, Jesse McNelis wrote:

    \On Wed, Jun 24, 2015 at 6:04 PM, J Decker wrote:
    Why aren't newlines just whitespace? I can easily string together a program
    all on one line using just spaces and it would build just fine, there's no
    required usage of newlines... but there is deliberate disallowing of
    them.

    It's a trade off, we trade newlines not being just white space for not
    having to type semicolons at the end of each line.
    It's a good trade off.
    Yes but both of these things aren't ; related.. they're bounded by ( and )

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • J Decker at Jun 24, 2015 at 3:48 pm

    On Wed, Jun 24, 2015 at 7:50 AM, Paul Borman wrote:

    In the formal Go grammar, newlines are actually just white space. The
    lexer, however, treats newlines special in order to let code elide the ;'s
    : https://golang.org/ref/spec#Semicolons

    I see; while I read that before what it meant didn't really click until
    now.
    I guess using '\n' as a magic ';' does come with some hidden requirements.
    Requirements that diminish readability and utility unfortunately.



    What does the following code mean?

    a = 1
    b = 2

    Without the lexical rule of adding semicolons, those lines become:

    a = 1 b = 2

    but it's still not unparsable, and I don't think there's any way to
    reinterpret that as anything other than a=1 and b=2 as two separate ideas.
    I did take some time and attempt to reduce a program to a single line. and
    found I had to add ';' between statements...

    It had seemed to me that ';' had more become optional than replaced by
    something else...

    I don't think we want that language. Even if you consider the unclosed (,
    what about:

    foo(bar(), func() { a = 1
    b = 2
    })

    That results in the "a =1 b = 2" issue from above.

    var a int = 1
             + 2
      and I see now that the EOL terminator causes +2 to be a unused expression
    except where there's an operator to ignore the EOL

    var a int = 1 +
             2

    even though if another IDENT was found it could just clear the lexing
    state/flush the prior statement and begin collecting a new statement... and
    really adding

    var a int = 1
                       + 2 b = 3
                              -5

    isn't unknowable.

    The most confusing I could think of would be a function returning a
    function...(which I'm not even sure is a valid construct in go)

    r := f( args )( args_to_f_result )



    It might be possible that looking ahead to the next token could be used to
    refine when a ; is added or not, but I am not sure of what issues that
    might introduce.

    I can see that looking ahead to see if the next thing is an operator might
    also be a fix (While responding up to this point with new understanding
    that was my thought); although gofmt would have to either stop outputting
    cave drawings and output blueprints; or at least not mangle existing
    formatting (operator postifxed or suffixed to an expression part), which
    would also be an issue.... but the look-ahead in the case of a '-' operator
    could be an issue

    Also see that gofmt would have to learn indenting with spaces for continued
    expressions

    --- gofmt output of simple case
    func main() {
             var a int = 1 +
                     -2
             fmt.Println("use a", a)
    }
    -------
    but it doesn't align correctly under assignment or opening parentheses
    either... although it does indent if the operator is postfixed to the
    leading expression part

    ---------
    unrelated and just a comment....
    ------ unformatted ------
             for i := range strings {
             C.free( unsafe.Pointer( strings[i] ) );
             }
    ---- formatted ----
    for i := range strings {
    C.free(unsafe.Pointer(strings[i]))
    }
    -------------------

    I strongly disagree in having spaces stripped in parentheses; at least
    spaces are kept around operators and after commas. But other than that and
    the occasional spurious ';'s my go code matches gofmt... (well and
    formatting of long expressions, which just can't be formatted well as it
    stands)

         -Paul
    On Wed, Jun 24, 2015 at 7:25 AM, J Decker wrote:



    On Wed, Jun 24, 2015 at 1:17 AM, Jesse McNelis <jessta@jessta.id.au>
    wrote:
    \On Wed, Jun 24, 2015 at 6:04 PM, J Decker wrote:
    Why aren't newlines just whitespace? I can easily string together a program
    all on one line using just spaces and it would build just fine,
    there's no
    required usage of newlines... but there is deliberate disallowing of
    them.

    It's a trade off, we trade newlines not being just white space for not
    having to type semicolons at the end of each line.
    It's a good trade off.
    Yes but both of these things aren't ; related.. they're bounded by ( and )

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Paul Borman at Jun 24, 2015 at 4:28 pm

    The most confusing I could think of would be a function returning a
    function...(which I'm not even sure is a valid construct in go)
    r := f( args )( args_to_f_result )

    You certainly can have a function return a function (
    http://play.golang.org/p/zCvW2NgwSH):

    package main

    import "fmt"

    func foo(a string) func(b string) string {
    return func(b string) string {
    return a + " " + b
    }
    }
    func main() {
    fmt.Println(foo("hello")("world"))
    }


    As for gofmt and formatting, there are lots of nits I have with gofmt. The
    rules for when to or when not to insert spaces and continuation indents
    among them. That said, those little nits pale in comparison to the
    benefits of a mostly uniform formatting standard. K&R had a definite style
    for C, one which I found easy to ready (it is what I first learned). Here
    are just a few variations I have seen since then:

             if (a == b)
                     x = 1;
             else
                     x = 2;

             if (a == b) {
                     x = 1;
             } else {
                     x = 2;
             }

             if ( a == b ) {
                     x = 1;
             } else {
                     x = 2;
             }

             if( a == b ){
                     x = 1;
             }else{
                     x = 2;
             }

             if(a==b){
                     x=1;
             }else{
                     x=2;
             }

             if (a == b)
             {
                     x = 1;
             }
             else
             {
                     x = 2;
             }


             if (a == b)
                 {
                     x = 1;
                 }
             else
                 {
                     x = 2;
                 }

             if (a == b) {
               x = 1;
             }
             else {
               y = 2;
             }

             if (a == b) x = 1;
             else x = 2;

             IF a == b THEN
                     x = 1;
             ELSE
                     x = 2;
             ENDIF

             int main() {
                     printf("hello world\n")
             }

             int
             main() {
                     printf("hello world\n")
             }

             int
             main()
             {
             printf("hello world\n")
             }

             int
             main()
                     {
                     printf("hello world\n")
                     }

             int
                     main()
             {
                     printf("hello world\n")
             }

    I have seen all of these different styles in C code (sometimes many of them
    in the same file or function!) I didn't even get into the myriad of ways
    people do continuation lines in C these days. While these small snippets
    may not seem a big deal, when you start getting files of them your ability
    to scan code becomes strained. When you start have huge code bases it
    becomes even more important.

    I am very happy that the Go language itself (this does not include
    packages) is still tightly controlled by a small set (was 3, hopefully
    still the same) of intelligent people who have (had?) a rule that if all
    three did not agree it did not go in. This has kept Go consistent, simple,
    and straightforward. This has led to tools like gofmt and the relative
    consistency of the standard library and other packages. It may not be
    perfect, but I have found it better than the alternatives I have lived
    through.

    I would much prefer to use a package that rated 4½ gophers than one that
    only rated 1½ gophers, even if the latter had slightly faster algorithms or
    slightly more features.

    I rue the day that there is a ANSI Standard Go definition and POSIX
    Standard Go Library.

         -Paul
    On Wed, Jun 24, 2015 at 8:48 AM, J Decker wrote:


    On Wed, Jun 24, 2015 at 7:50 AM, Paul Borman wrote:

    In the formal Go grammar, newlines are actually just white space. The
    lexer, however, treats newlines special in order to let code elide the ;'s
    : https://golang.org/ref/spec#Semicolons

    I see; while I read that before what it meant didn't really click until
    now.
    I guess using '\n' as a magic ';' does come with some hidden
    requirements. Requirements that diminish readability and utility
    unfortunately.



    What does the following code mean?

    a = 1
    b = 2

    Without the lexical rule of adding semicolons, those lines become:

    a = 1 b = 2

    but it's still not unparsable, and I don't think there's any way to
    reinterpret that as anything other than a=1 and b=2 as two separate ideas.
    I did take some time and attempt to reduce a program to a single line. and
    found I had to add ';' between statements...

    It had seemed to me that ';' had more become optional than replaced by
    something else...

    I don't think we want that language. Even if you consider the unclosed (,
    what about:

    foo(bar(), func() { a = 1
    b = 2
    })

    That results in the "a =1 b = 2" issue from above.

    var a int = 1
    + 2
    and I see now that the EOL terminator causes +2 to be a unused expression
    except where there's an operator to ignore the EOL

    var a int = 1 +
    2

    even though if another IDENT was found it could just clear the lexing
    state/flush the prior statement and begin collecting a new statement... and
    really adding

    var a int = 1
    + 2 b = 3
    -5

    isn't unknowable.

    The most confusing I could think of would be a function returning a
    function...(which I'm not even sure is a valid construct in go)

    r := f( args )( args_to_f_result )



    It might be possible that looking ahead to the next token could be used to
    refine when a ; is added or not, but I am not sure of what issues that
    might introduce.

    I can see that looking ahead to see if the next thing is an operator
    might also be a fix (While responding up to this point with new
    understanding that was my thought); although gofmt would have to either
    stop outputting cave drawings and output blueprints; or at least not mangle
    existing formatting (operator postifxed or suffixed to an expression part),
    which would also be an issue.... but the look-ahead in the case of a '-'
    operator could be an issue

    Also see that gofmt would have to learn indenting with spaces for
    continued expressions

    --- gofmt output of simple case
    func main() {
    var a int = 1 +
    -2
    fmt.Println("use a", a)
    }
    -------
    but it doesn't align correctly under assignment or opening parentheses
    either... although it does indent if the operator is postfixed to the
    leading expression part

    ---------
    unrelated and just a comment....
    ------ unformatted ------
    for i := range strings {
    C.free( unsafe.Pointer( strings[i] ) );
    }
    ---- formatted ----
    for i := range strings {
    C.free(unsafe.Pointer(strings[i]))
    }
    -------------------

    I strongly disagree in having spaces stripped in parentheses; at least
    spaces are kept around operators and after commas. But other than that and
    the occasional spurious ';'s my go code matches gofmt... (well and
    formatting of long expressions, which just can't be formatted well as it
    stands)

    -Paul
    On Wed, Jun 24, 2015 at 7:25 AM, J Decker wrote:



    On Wed, Jun 24, 2015 at 1:17 AM, Jesse McNelis <jessta@jessta.id.au>
    wrote:
    \On Wed, Jun 24, 2015 at 6:04 PM, J Decker wrote:
    Why aren't newlines just whitespace? I can easily string together a program
    all on one line using just spaces and it would build just fine,
    there's no
    required usage of newlines... but there is deliberate disallowing of
    them.

    It's a trade off, we trade newlines not being just white space for not
    having to type semicolons at the end of each line.
    It's a good trade off.
    Yes but both of these things aren't ; related.. they're bounded by ( and
    )

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • J Decker at Jun 24, 2015 at 7:17 pm
    On Wed, Jun 24, 2015 at 9:28 AM, Paul Borman wrote:
    As for gofmt and formatting, there are lots of nits I have with gofmt.
    The rules for when to or when not to insert spaces and continuation indents
    among them. That said, those little nits pale in comparison to the
    benefits of a mostly uniform formatting standard. K&R had a definite style
    for C, one which I found easy to ready (it is what I first learned). Here
    are just a few variations I have seen since then:
    (very long list there)

    yes I see that point. and that was certainly more of a *shrug* on my part
    at the end...
    was more of a comment that I do agree with most of formatting... even
    if<nospace>( to become if<sp>( ... but that's because I know that in simple
    cases I don't even need the open parentheses. I'm glad they didn't include
    'then' And understanding \n as a ; makes '} else {' more acceptable as an
    inevitability rather than a formatting choice. and certainly whether
    there's a space within '( )'s or not is like liking apples or oranges more.

    But the expression continuation; I really thought was based on '100's of
    thousands of people learned it this way in school, 10's of thousands of
    companies that have formatting policy written this way, and the thousands
    of leaders have never done it any other way.... why not make it an absolute
    formatting condition? '

    re: K&R for C?
    int
    main( argc, argv )
        int argc;
        char ** argv;
    {
    }

    horrible-est :) (and zlib code is still in that format) I certainly don't
    mind having functions on one line, other than the parameter comma
    continuations should be on the next line, under the parenthesis. But if
    your parameter list is excessively long (thinking about the one case) maybe
    consider making some structs to pass instead.

    Why I bothered at all was the long expressions. and I wonder if there's a
    distinction between 'a = 3 -2' and a = 3 - 2'... I guess there is, it would
    have to be subtraction operator and not negate operator....

    ---- gofmt output of some expressions -------
             var a int = 1 + -f()
             var d int = 1 - f()
             var b int = 1 + -2
             var c int = ((1 + 2) / (3 + 4))
    ---------------------------------------------------------

             var c int = ((1 + 2)
                         / (3
                           + 4))

    (plus or not a space... I could see it either way to format under or within
    the open paren)

             var c int = ((1 + 2)
                          / (3
                             + 4))

    and
        a = 1
          - 2;

    (again plus or not a space... but tab to same overall level, and spaces to
    fill to position)

    So proposition as an exception to

    https://golang.org/ref/spec#Semicolons

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

        - one of the operators and delimiters
        <https://golang.org/ref/spec#Operators_and_Delimiters> ++, --, ), ], or }

    add (except when)...

    <strike idea="bad">
    a semicolon is NOT automatically inserted into the token stream at the end
    of a non-blank line if the (next line's first token/next token in the
    stream) is

        - one of the operators and delimiters
        <https://golang.org/ref/spec#Operators_and_Delimiters> that is not ++, --,
        {, (, or [

    </strike>


    a semicolon is NOT automatically inserted at the end of a non-blank line if
    the end is

        - Immediately within () or [] ( " ".. strings already have to be
        terminated before leaving the line; if the immediate enclosure were { }
        this should not apply, hence the immediate modifier )

    ------- cut ------------
    (this invalidates the first modification)

    Looking at all of the operators... (and then it hit me that * is still used
    to dereference a pointer)... but all other operators will cause other sorts
    of errors. Although it's the non-errors that might be most tricky... Such
    as a leftover result of some class that you didn't mean to reference with a
    ==

    r := f( 1 )
          == 3

    and it would require a manual semi-colon

    r := f( 1 );
          == 3

    to get a error that you missed some part of the expression; but the thought
    was that all lines that start with an operator are probably invalid and
    shouldn't be written...

    var r, p *int
    r = p
    *p = 4

    would then require a ';' when 99% of the time you don't need them....

    a ++ b; // would just be wrong
    a++ b; // unexpected/unused b
    a ++b; // unused a

    So the definition of this corner case is becoming too rigid; if it were
    additionally 'within () or []'...
    (**revised rule here... which eliminates most of these musings)

    ----------- end cut -----------
    As far as I know there's no ; allowed within bracketed or
    parenthized(parenthesized) expressions.


    gofmt seems to be line oriented; it doesn't gather expressions on multiple
    lines, and at least indents multiple levels. But, it complains with
    expression prefix operators for

             var c int = ((1 + 2)
    expected ')' and found newline
                          / (3
    expected statement, found '/'
                             + 4))


    has to be something like this for gofmt to output

             var c int = ((1 + 2) /
                     (3 +
                             4))

    instead of

             var c int = ((1
                     + -2)
                     / (3
                             + 4))

    It's not even like 'cvs' and fixing to always write line endings the same
    way they are in the repository regardless of system and carrying my own
    patch; it's a breaking issue with other users.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Paul Borman at Jun 24, 2015 at 8:11 pm
    For indentation, it is helpful to remember that Go, like most new things,
    is a reaction to something existing. There are many indentation styles
    (tab, 2 space, 4 space, 3 space, 8 space). At Google the standard indent
    is 2 spaces (try writing Python with 2 space indents, it is horrible (to
    me), but that is how we do it at Google). Go broke with that by saying an
    indent is a tab but did not define how many spaces are in a tab. If you
    like 2 space indents, find, use 2 space tabs. Lets take a simple example
    with an if statement:

    if (a == b && c == d) {
             hurray()
    }


    And then break it after the &&. With gofmt you get:

    if a == b &&
             c == d {
             hurray()
    }


    It is ugly. "Proper" indentation would be (with no disrespect about proper
    intended):

    if (a == b &&
         c == d) {
             hurray()
    }


    So far so good, but that is with 8 space tabs. Here are two other ways it
    might appear:

    if (a == b &&
         c == d) {
       hurray()
    }

    if (a == b &&
         c == d) {
         hurray()
    }


    Notice that the second of these two is actually the same as gofmt when tabs
    are 4 spaces and is no more readable than what gofmt produces even when
    tabs are 8 spaces.

    For a slightly different take, consider the (hideous) code:

    if veryLongFunctionName(withLongArguments, andAFunctionCall(withArg1,
    andAVeryLongSecondArg2)) {

             helpMe()
    }


    Here are two ways to break it up and what gofmt produces:

    if veryLongFunctionName(withLongArguments,
             andAFunctionCall(withArg1, andAVeryLongSecondArg2)) {
             helpMe()
    }
    if veryLongFunctionName(withLongArguments, andAFunctionCall(withArg1,
             andAVeryLongSecondArg2)) {
             helpMe()
    }

    if veryLongFunctionName(withLongArguments,
             andAFunctionCall(withArg1,
                     andAVeryLongSecondArg2)) {
             helpMe()
    }


    And here is what the "proper" indentation would result in:

    if veryLongFunctionName(withLongArguments,
                             andAFunctionCall(withArg1, andAVeryLongSecondArg2))
    {
             helpMe()
    }

    if veryLongFunctionName(withLongArguments, andAFunctionCall(withArg1,

    andAVeryLongSecondArg2)) {
             helpMe()
    }

    if veryLongFunctionName(withLongArguments,
                             andAFunctionCall(withArg1,
                                              andAVeryLongSecondArg2)) {
             helpMe()
    }


    (If you are using the gmail web app you may need a wide window to see this
    right. It does some odd formatting, and I hope as I send it it doesn't
    "fix" it for me"). This demonstrates two problems. One is that you should
    not use really long names, and 2, "proper" indentation doesn't look very
    pretty. BTW, in my C code I typically used "proper" indentation, so I am
    not opposed to the style, but it has its limits.

    As a side note. I have tabs set to 8 in my editor (nvi) as I write my Go
    code, but when I review it I have our code review tool set to 4 space
    tabs. It really makes unformatted code stand out!

    With Go I just don't break the line and live with the wrap. on my terminal
    screen. I don't find it aesthetic, but it was easy to adapt to and is very
    consistent. Gofmt has very simple rules. It is hard to make a beautiful
    automatic code formatter (I tried so hard to use indent for C code in the
    past, but it required way too many options to be specified, always had
    quirks, and each person ended up with different formatting anyhow,
    depending on their options). With gofmt I no longer waste time with such
    things. I just code away, often with horribly lazy indentation and then
    let gofmt fix it up for me. Having no options is what makes gofmt so
    useful. All gofmt'd code looks the same, which is great for readability.

         -Paul
    On Wed, Jun 24, 2015 at 12:17 PM, J Decker wrote:
    On Wed, Jun 24, 2015 at 9:28 AM, Paul Borman wrote:

    As for gofmt and formatting, there are lots of nits I have with gofmt.
    The rules for when to or when not to insert spaces and continuation indents
    among them. That said, those little nits pale in comparison to the
    benefits of a mostly uniform formatting standard. K&R had a definite style
    for C, one which I found easy to ready (it is what I first learned). Here
    are just a few variations I have seen since then:
    (very long list there)

    yes I see that point. and that was certainly more of a *shrug* on my part
    at the end...
    was more of a comment that I do agree with most of formatting... even
    if<nospace>( to become if<sp>( ... but that's because I know that in simple
    cases I don't even need the open parentheses. I'm glad they didn't include
    'then' And understanding \n as a ; makes '} else {' more acceptable as an
    inevitability rather than a formatting choice. and certainly whether
    there's a space within '( )'s or not is like liking apples or oranges more.

    But the expression continuation; I really thought was based on '100's of
    thousands of people learned it this way in school, 10's of thousands of
    companies that have formatting policy written this way, and the thousands
    of leaders have never done it any other way.... why not make it an absolute
    formatting condition? '

    re: K&R for C?
    int
    main( argc, argv )
    int argc;
    char ** argv;
    {
    }

    horrible-est :) (and zlib code is still in that format) I certainly don't
    mind having functions on one line, other than the parameter comma
    continuations should be on the next line, under the parenthesis. But if
    your parameter list is excessively long (thinking about the one case) maybe
    consider making some structs to pass instead.

    Why I bothered at all was the long expressions. and I wonder if there's a
    distinction between 'a = 3 -2' and a = 3 - 2'... I guess there is, it would
    have to be subtraction operator and not negate operator....

    ---- gofmt output of some expressions -------
    var a int = 1 + -f()
    var d int = 1 - f()
    var b int = 1 + -2
    var c int = ((1 + 2) / (3 + 4))
    ---------------------------------------------------------

    var c int = ((1 + 2)
    / (3
    + 4))

    (plus or not a space... I could see it either way to format under or
    within the open paren)

    var c int = ((1 + 2)
    / (3
    + 4))

    and
    a = 1
    - 2;

    (again plus or not a space... but tab to same overall level, and spaces to
    fill to position)

    So proposition as an exception to

    https://golang.org/ref/spec#Semicolons

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

    - one of the operators and delimiters
    <https://golang.org/ref/spec#Operators_and_Delimiters> ++, --, ), ],
    or }

    add (except when)...

    <strike idea="bad">
    a semicolon is NOT automatically inserted into the token stream at the end
    of a non-blank line if the (next line's first token/next token in the
    stream) is

    - one of the operators and delimiters
    <https://golang.org/ref/spec#Operators_and_Delimiters> that is not ++,
    --, {, (, or [

    </strike>


    a semicolon is NOT automatically inserted at the end of a non-blank line if
    the end is

    - Immediately within () or [] ( " ".. strings already have to be
    terminated before leaving the line; if the immediate enclosure were { }
    this should not apply, hence the immediate modifier )

    ------- cut ------------
    (this invalidates the first modification)

    Looking at all of the operators... (and then it hit me that * is still
    used to dereference a pointer)... but all other operators will cause other
    sorts of errors. Although it's the non-errors that might be most tricky...
    Such as a leftover result of some class that you didn't mean to reference
    with a ==

    r := f( 1 )
    == 3

    and it would require a manual semi-colon

    r := f( 1 );
    == 3

    to get a error that you missed some part of the expression; but the
    thought was that all lines that start with an operator are probably invalid
    and shouldn't be written...

    var r, p *int
    r = p
    *p = 4

    would then require a ';' when 99% of the time you don't need them....

    a ++ b; // would just be wrong
    a++ b; // unexpected/unused b
    a ++b; // unused a

    So the definition of this corner case is becoming too rigid; if it were
    additionally 'within () or []'...
    (**revised rule here... which eliminates most of these musings)

    ----------- end cut -----------
    As far as I know there's no ; allowed within bracketed or
    parenthized(parenthesized) expressions.


    gofmt seems to be line oriented; it doesn't gather expressions on multiple
    lines, and at least indents multiple levels. But, it complains with
    expression prefix operators for

    var c int = ((1 + 2)
    expected ')' and found newline
    / (3
    expected statement, found '/'
    + 4))


    has to be something like this for gofmt to output

    var c int = ((1 + 2) /
    (3 +
    4))

    instead of

    var c int = ((1
    + -2)
    / (3
    + 4))

    It's not even like 'cvs' and fixing to always write line endings the same
    way they are in the repository regardless of system and carrying my own
    patch; it's a breaking issue with other users.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • J Decker at Jun 25, 2015 at 12:03 am

    On Wed, Jun 24, 2015 at 1:11 PM, Paul Borman wrote:

    For indentation, it is helpful to remember that Go, like most new things,
    is a reaction to something existing. There are many indentation styles
    (tab, 2 space, 4 space, 3 space, 8 space). At Google the standard indent
    is 2 spaces (try writing Python with 2 space indents, it is horrible (to
    me), but that is how we do it at Google). Go broke with that by saying an
    indent is a tab but did not define how many spaces are in a tab. If you
    like 2 space indents, find[fine], use 2 space tabs. Lets take a simple
    example with an if statement:

    if (a == b && c == d) {
    hurray()
    }


    And then break it after the &&. With gofmt you get:

    if a == b &&
    c == d {
    hurray()
    }


    except, it's also asserted that continued expressions should have their
    operator lead the line, which immediately distinguishes them as
    continuation of above and not a new line....


    if a == b
             && c == d {
             hurray()
    }


    and again these (reformated in quote)

    Here are two ways to break it up and what gofmt produces:
    if veryLongFunctionName(withLongArguments
    , andAFunctionCall(withArg1, andAVeryLongSecondArg2)) {
    helpMe()
    }
    if veryLongFunctionName(withLongArguments, andAFunctionCall(withArg1
    , andAVeryLongSecondArg2)) {
    helpMe()
    }

    if veryLongFunctionName(withLongArguments
    , andAFunctionCall(withArg1
    , andAVeryLongSecondArg2)) {
    helpMe()
    }


    And here is what the "proper" indentation would result in:

    if veryLongFunctionName(withLongArguments,
    , andAFunctionCall(withArg1,
    andAVeryLongSecondArg2)) {
    helpMe()
    }

    if veryLongFunctionName(withLongArguments, andAFunctionCall(withArg1
    ,
    andAVeryLongSecondArg2)) {
    helpMe()
    }

    if veryLongFunctionName(withLongArguments
    , andAFunctionCall(withArg1
    , andAVeryLongSecondArg2)) {
    helpMe()
    }


    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Nigel Tao at Jun 25, 2015 at 12:33 am

    On Thu, Jun 25, 2015 at 10:03 AM, J Decker wrote:
    except, it's also asserted that continued expressions should have their
    operator lead the line, which immediately distinguishes them as continuation
    of above and not a new line....
    There are many assertions about which programming style is 'best', and
    some assertions conflict. Tabs vs spaces is the obvious example, but
    there are many others, and I'm sure there exist conflicting assertions
    that operators should be at the start or the end of lines.

    gofmt's style was not 100% equal to my personal preference, but I'm
    happy to lose the battle to end the battle. Its rules are simple. Its
    results are consistent.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • J Decker at Jun 26, 2015 at 3:26 pm
    Did some digging, found scanner.go which seemed to implement handling the
    newline-semicolon replacement. But, after making modifications, found that
    scanner is only given a part of .go files that is up to all imports.
    Although, this also revealed that semicolons were used in the import
    statement in parenthesis, so there goes that theory that semicolons weren't
    used in parentheses.

             for

             { fmt.Println( "10 goto 10" ) }


    http://golang.org/ref/spec
       search ";" } ")"

    import()
    const()
    struct()
    var()

    ------
    So it's a fairly complex thing to modify the behavior. Depressing, but
    understandable.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jan Mercl at Jun 26, 2015 at 3:33 pm

    On Fri, Jun 26, 2015 at 5:26 PM J Decker wrote:

    Did some digging, found scanner.go which seemed to implement handling the
    newline-semicolon replacement. But, after making modifications, found that
    scanner is only given a part of .go files that is up to all imports.
    Although, this also revealed that semicolons were used in the import
    statement in parenthesis, so there goes that theory that semicolons weren't
    used in parentheses.

    For the current Go release: Semicolon injection is armed at [0], performed
    at [1].

    [0]:
    https://github.com/golang/go/blob/release-branch.go1.4/src/cmd/gc/lex.c#L1620
    [1]:
    https://github.com/golang/go/blob/release-branch.go1.4/src/cmd/gc/lex.c#L903
    --

    -j

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Adam willis at Jun 24, 2015 at 2:39 pm
    This is an issue of a poorly designed lexer. This issue could be easily
    fixed but unfortunately five people would have to die to get this into the
    codebase.
    On Wednesday, June 24, 2015 at 4:04:59 AM UTC-4, J Decker wrote:

    Why aren't newlines just whitespace? I can easily string together a
    program all on one line using just spaces and it would build just fine,
    there's no required usage of newlines... but there is deliberate
    disallowing of them.

    I thought it odd that I couldn't put opening { on a newline, and sure,
    brevity of not having empty lines with just a { on them sort of makes
    sense; although to me makes code less legible... since there's no
    requirement to actually indent after a { opening block either.

    But that I can't format code with continued lines with the operator
    leading into the next line, and have to put it at the end of the prior line
    is just unbearable.

    for instance...

    if( a > 0
    b > 0 ) {}
    in many simple cases it doesn't matter... but if I have a fairly complex
    condition with long meaningful identifiers, then I have to search all the
    way to the end of the line to figure out what the operator is.

    Similarly...

    fmt.Println( "... : ", val1
    , " .... : ", val2
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Adam willis at Jun 24, 2015 at 2:40 pm
    Ok, maybe not die, just disappear.
    On Wednesday, June 24, 2015 at 10:38:59 AM UTC-4, adam willis wrote:

    This is an issue of a poorly designed lexer. This issue could be easily
    fixed but unfortunately five people would have to die to get this into the
    codebase.
    On Wednesday, June 24, 2015 at 4:04:59 AM UTC-4, J Decker wrote:

    Why aren't newlines just whitespace? I can easily string together a
    program all on one line using just spaces and it would build just fine,
    there's no required usage of newlines... but there is deliberate
    disallowing of them.

    I thought it odd that I couldn't put opening { on a newline, and sure,
    brevity of not having empty lines with just a { on them sort of makes
    sense; although to me makes code less legible... since there's no
    requirement to actually indent after a { opening block either.

    But that I can't format code with continued lines with the operator
    leading into the next line, and have to put it at the end of the prior line
    is just unbearable.

    for instance...

    if( a > 0
    b > 0 ) {}
    in many simple cases it doesn't matter... but if I have a fairly complex
    condition with long meaningful identifiers, then I have to search all the
    way to the end of the line to figure out what the operator is.

    Similarly...

    fmt.Println( "... : ", val1
    , " .... : ", val2
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Konstantin Khomoutov at Jun 24, 2015 at 3:59 pm

    On Wed, 24 Jun 2015 07:38:59 -0700 (PDT) adam willis wrote:

    This is an issue of a poorly designed lexer. This issue could be
    easily fixed but unfortunately five people would have to die to get
    this into the codebase.
    Why don't you just fork Go and make it your own language done right
    rather than persistently flinging poos from the sidelines?

    Your right to possess any opinion on anything is not questioned but
    persistent barking on the same tree lowers the signal-to-noise ratio on
    the threads here, so really could you may be please funnel your
    writing energy into some more constructive venue? Thanks.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • John Weldon at Jun 24, 2015 at 4:08 pm
    From what I've seen Adam has been a fairly constructive participant in this
    forum, apart from occasional acerbic comments toward Google. I'd
    appreciate less negativity, but I certainly don't see the signal-to-noise
    ratio being lowered by Adam - at least no more than many others who also
    bring value to the discussion :)

    On Wed, Jun 24, 2015 at 8:58 AM, Konstantin Khomoutov wrote:

    On Wed, 24 Jun 2015 07:38:59 -0700 (PDT)
    adam willis wrote:
    This is an issue of a poorly designed lexer. This issue could be
    easily fixed but unfortunately five people would have to die to get
    this into the codebase.
    Why don't you just fork Go and make it your own language done right
    rather than persistently flinging poos from the sidelines?

    Your right to possess any opinion on anything is not questioned but
    persistent barking on the same tree lowers the signal-to-noise ratio on
    the threads here, so really could you may be please funnel your
    writing energy into some more constructive venue? Thanks.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Russ Cox at Jun 24, 2015 at 4:27 pm

    On Wed, Jun 24, 2015 at 10:38 AM, adam willis wrote:

    This is an issue of a poorly designed lexer.
    Go is defined by a specification, not an implementation. Either the lexer
    does what the spec requires or not; the design of the lexer, good or bad,
    is not relevant.

    The design of this part of the spec was driven by motivations other than
    the effect on lexing. In particular, the goal was to have a semicolon
    insertion rule that was as easy as possible for users to understand. The
    rule Go uses depends on the previous token only, not what came before, not
    what's coming next, not the broader parse context. We took this route based
    in part on direct experience with the confusion that results from
    Javascript's much more sophisticated but more often mysterious semicolon
    insertion rule.

    For more details, see the original proposal for semicolon insertion at
    https://groups.google.com/d/msg/golang-nuts/XuMrWI0Q8uk/kXcBb4W3rH8J.

    One might refine your point to say that the semicolon insertion rule is an
    issue of a poorly designed language grammar, but the beginning of that
    proposal explains why this is not the case:

    One syntactic idea we tried was to reduce the number of semicolons in the
    grammar, to make the source code cleaner-looking. We managed to get rid of
    many of them, but the grammar became clumsy and hard to maintain as we
    worked on the compiler, and we realized we had overreached. We backed up to
    a compromise that had optional semicolons in a few places, a couple of
    rules about where they go, and a tool (gofmt) to regularize them.


    And later:

    This proposal may remind you of JavaScript's optional semicolon rule, which
    in effect adds semicolons to fix parse errors. The Go proposal is
    profoundly different. First, it is a lexical model, not a semantic one, and
    we believe that makes it far safer in practice. The rules are hard and
    fast, not subject to contextual interpretation. Second, since very few
    expressions in Go can be promoted to statements, the opportunities where
    confusion can arise are also very few - they're basically the examples
    above. Finally, since Go is statically type-safe, the odds are even lower.


    It's short and worth reading in full if you haven't seen it before. (It's
    dated December 9, 2009, so I believe it is the first change proposal
    circulated during the open source phase of Go's development.)

    Russ

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJun 24, '15 at 8:04a
activeJun 26, '15 at 3:33p
posts20
users11
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase