Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I really enjoyed the keynote.

The joke about the profound error of using whitespace just shows how partisan these discussions are. In go, with the semi-colon insertion rules and with gofmt, there is an implicit whitespace rule all over again.

Personally, I like whitespace because its how my mind reads code. Its nice in Python, mostly because of how concise Python is to read. Its a bit of a bind in Java, where you don't trust tools to roll-up functions but on the other hand they all seem so long and full of boilerplate. With gofmt, the go world lives in a significant whitespace world they just don't want to admit it :)



> The joke about the profound error of using whitespace just shows how partisan these discussions are. In go, with the semi-colon insertion rules and with gofmt, there is an implicit whitespace rule all over again.

Other than lisps, most languages have significant whitespace -- treating, for instance, newlines as having an important distinctions from other whitespace.


> In go, with the semi-colon insertion rules and with gofmt, there is an implicit whitespace rule all over again.

So this is technically correct (and I had never though about that before, so thank you for pointing that out!). However, I think '\n' and '\r' are not directly comparable to '\t' and ' ' characters.

All whitespace is only visible by its boundaries (kinda like certain 70s minimalist sculpture, actually). Newlines affect vertical structure, whereas tabs and spaces affect horizontal structure. So far it's the same.

However, we don't read text vertically, we read it horizontally (I know there are exceptions, but not in any significant programming languages that I know of). As a result we don't group characters by vertical whitespace the same way as we group characters by horizontal whitespace: in most natural languages, the difference is paragraph separation vs word/sentence separation. Programming languages also follow this coarse/refined level. Think about how we construct indented text in programming languages: relative to the vertical position.

So I would say that while both cases have the problem that we can only observe whitespace by the characters that surround them, in the vertical whitespace that happens at a coarser, less ambiguous level than horizontal whitespace. And I think that's why using significant newlines should be less failure prone than significant tabs/spaces.


> However, we don't read text vertically, we read it horizontally (I know there are exceptions, but not in any significant programming languages that I know of).

I think we do read code vertically and it is significant in all programming languages, and I think that it is a core problem with acceptance of Lisps, because they unusually strongly avoid leveraging the two-dimensional nature of typical code editing environments in favor of having pretty much the perfect purely-horizontal syntax.

> So I would say that while both cases have the problem that we can only observe whitespace by the characters that surround them, in the vertical whitespace that happens at a coarser, less ambiguous level than horizontal whitespace.

I do think there is an ambiguity difference, but its not because we read horizontally but not vertically, but because horizontal whitespace in common use -- i.e., that people are used to using on a keyboard in the context of programming -- is limited to newlines (and, while there are different means of expressing newlines, they are mostly driven by platform rather than personal preference and are, in any case, easy to account for), whereas tab/space holy wars are as old as line oriented PLs that allow indentation (whether they are sensitive to it or not).


> I think we do read code vertically and it is significant in all programming languages

Of course it is significant, I was agreeing with you there! But my point was:

d

o

_

y

o

u

_

e

v

e

r

_

w

r

i

t

e

_

c

o

d

e

_

l

i

k

e

_

t

h

i

s

?

But maybe I should have worded it differently: we read text in "row-major order", not "column-major order". That's basically the difference I talk about.

Also, there is another difference between newlines and indentation: newlines only go "forward" (next line), whereas with indentation you go back and forth into levels of indentation. It's not the same. The closest thing I can think of is that one language where you could write the exponent of a formula on a line before, faking superscript, or the index of a formula on the next, faking subscript. Making mono-typed source code look like math formulas basically (and probably a pain to type out). That's the only programming context I can think of where newlines are actually significant in a similar fashion to indentation.


> In go, with the semi-colon insertion rules and with gofmt, there is an implicit whitespace rule all over again.

Can you explain what this means?


It means that you have to be careful about how you treat whitespace (mostly newlines and how they relate to curly braces), otherwise a semicolon could be inserted where it shouldn't or gofmt could format your code in a way you didn't mean to. So, the whitespace is significant in Go too.


Newlines are important, but that's true of pretty much every language. Go does have more stringent requirements on where open braces are placed, but it's not a hard rule to remember (they always go on the same line as the code that opens the new scope). Also, this rule makes your code significantly less prone to breakage from errant edits and merges, since inserting a line can never separate your brace from the line it goes with. In this way, Go is actually more robust with respect to whitespace than almost any other language.

Note that in languages that don't mandate the open brace be on the same line as the code that opens the new scope, this can happen during a merge:

  // original code
  if (foo) 
  {
       printf("foo is true!")
  }

  // after the merge
  if (foo)
      someFunction()
  {
      printf("foo is true!")
  }
Now this code will always print "foo is true!". Because Go requires the open brace to be on the same line as the if, this type of bug is impossible in Go.

Gofmt will never change the behavior of your code, so you don't have to "worry" about what it will do. It only makes cosmetic changes to code, never functional.


I think the way Go treats coding styles is great. I don't have any problems following a one true convention enforced by the language and being aware about the minute details of code structuring in order to avoid problems in translation. Funnily, the language that taught me all that was Python.

As willvarfar points out, I feel Rob Pike is being disingenous when he talks about this. Golang uses less significant whitespace than Python, but it exists, the difference is in degree. If he prefers to minimize the impact of whitespace in Go code, that's fine. But why does he have to talk about it as an error or misjudgment?

If significant whitespace is such a bad idea, why do exist keywords that require whitespace around them in Go (package, func, type, etc.? Why can't I use whitespace in names in Go? This didn't happen in good old FORTRAN ;)


This seems like a logical fallacy. Of course you have to separate your language's tokens with something. This is not "significant" whitespace. It's token delimiters, and they don't generally need whitespace. for example func(){return 1} has no whitespace between func and the open paren, also

    func        (){     
            a := 1
                          return a

             }
while ugly, this still compiles just fine. It would compile just as fine if you randomly flipped some of the spaces into tabs.

Whitespace is not significant in Go.

The difference between significant whitespace and requiring "some" whitespace is that if you did something like that in Python, you could end up with a program with different logic depending on which spaces were flipped to tabs. This is why mixing spaces and tabs in Python is verboten.

In go, you can mix spaces and tabs all you want, wherever you want in your code and it will never ever change the logic of your code, period. (obvious exceptions for changes inside string literals)

So, it's not really a matter of degrees, and Python's method is completely broken if you ever mix tabs and spaces, which as Rob Pike points out, are completely indistinguishable in the default views of most editors.


Did you know that almost all your example is perfectly doable in Python? Try this:

  def       my_func     (      )    :
      
      a        =      1

      return       a
It will run without a problem because only leading space is significant. Then you can mix tabs and spaces, add the space you want, blank lines, etc.

The Python coding style guideline (PEP 8) is very specific in that it recommends the use of 4 leading spaces per level. You can use a very simple program with regular expressions to solve any problem you could have in the mix of tabs and spaces in your files.

Now, try this example in FORTRAN.

  parameter(x=2)
  print*,"The parameter is ",x
Why can't I use commas or parentheses to delimit all the tokens in Go? Why does it insert semicolons without asking? Is such an arbitrary and problematic decision as the significant leading whitespace in Python.


I didn't specifically take the time to make code that would break in python, obviously, I could, and it would be trivial to do so.

Yes, it's just leading spaces that are different in Python, I know. I actually like python, but the space indenting is fragile.


It's similarly trivial to make syntactically correct code that breaks in Go. Example:

  if (a == 1) {
      return a }
  else { return b }
This won't compile in Go. But whitespace wasn't significant in Go, right? Take out the curly braces, add a couple of colons and this will run without a problem in Python.

My point is, there isn't such a big difference between Go and Python. Significant whitespace doesn't mean "whatever Python does differently", it means that whitespace is syntactically meaningful. Any whitespace in any part of your program has the potential for changing the meaning of it. If it does, then it's significant.

It's trivial to make a text editor show tabs and insert spaces even if you press tab. It's trivial to make a program that will switch leading tabs for the number of spaces that you want from a file. I don't say it's trouble-free, but it isn't such a big issue; and automatic semicolon insertion isn't trouble-free either, as you can see. You won't have problems with any of them if you take a little care.

In Python, leading whitespace and newlines are syntactically significant. In Go, newlines are in many cases syntactically significant. In both of them space around many keywords is significant (try to write packagemain in Go, see how it goes), and you can't put whitespace in names.


Sorry, I forgot, you can also do this in Python:

  def my_func():a=1;return a;
Try it, it works!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: