Hacker News new | past | comments | ask | show | jobs | submit login
Refactoring with go fmt (spf13.com)
86 points by spf13 on Nov 13, 2013 | hide | past | favorite | 40 comments



As a C coder I really wish it had a standard syntax and a similar tool to deal with that. Dealing with proper style is a constant headache among a team. And I always feel like a "coding style nazi" when I bother other people to tell them "you should put spaces here", "your braces are not in the correct position", "you shouldn't use TABs there" etc...

So in the end I stop doing it (or I let small mistakes go by) and soon enough the whole codebase is heterogeneous and looks like crap everywhere.

I don't really care about Go and never used it but this is a very good move on their part IMO. No bickering allowed, it's standard. No arguing, just run "go fmt" and you're set. Brilliant.


There are tools for standardizing C formatting. Another poster mentioned indent. Clang-format [1] is very good, works with C++ as well as C, and has great editor integration. You can choose among predefined style (e.g. Google, Mozilla, LLVM style guides) or create your own and then and enforce it within a source tree very easily.

[1]: http://clang.llvm.org/docs/ClangFormat.html


In addition to being instructions for the compiler, source is also a text designed to be read. Specifying and universally enforcing too rigid a rule-set is a bad idea. Good authors sometimes need to break rules in order to make a text better.

Imagine if novels were put through Microsoft Word spelling and grammar check just prior to publication and automatically had all the changes accepted.

The python style guide gets this right, quoting Emerson's famous maxim that "A foolish consistency is the hobgoblin of little minds."


Can you say where `go fmt` gets it wrong -- give an example. Or where a consistent formatting has gone wrong, in any language? I prefer 2 space python, but I don't have a better reason than my team, as a majority, prefer condenser line lengths, but it can be a problem having to gear up to work with a lib that follows PEP8 to the t.


How would the c equivalent of fmt layout duff's device, and would it be clearer or less clear than Tom Duff's original formatting (http://www.lysator.liu.se/c/duffs-device.html)?


I agree and disagree -- I don't like the idea of C having a standard syntax, but I would like having a simple program people run their code through the points out any format mistakes. I think in general you could easily handle this using a simple perl script or similar, just require people to run their code through it before submitting. Then it's simple, and you can just point to the program to use and policy for submitting code if someone breaks syntax.


Easy, integrate indent in the source control checkin hooks.

No more arguing.


This is conceptually nice. But consider. You want to fork a third party library. On check in you reformat the entire code base? Or, if you don't do it on initial commit, and then somebody needs to modify one line?

Recognize that "third party" might not mean some code base from NVIDIA or whatever, but just some code from 5 years ago in your own company.

And sure, we could enforce the same tool chain on the entire company, but then you have broken diff on probably every line of code in every repository. And the embedded guys are up in arms because it makes bad decisions for their hardware, which is limited to 40 column displays. And so on.

Go got it right. They had green field development, and made the decision on formatting then. I'm not crazy about a few of the specific choices they made, but who cares, really?

Personally, I would like a tool that inspected the code, recognized the style, and then enforced that style. Braces on the same line, well, that is how all new lines will be formatted. And so on. I live and die by source code diffs, and don't want formatting wars to break that. I also spend every day in multiple code bases not written by the company, so I already deal with different formatting styles. It ain't hard to deal with, excepting that terrible Microsoft C style of spacing ('foo( x ,y )' vs 'foo (x, y)'. My eyes can't parse that quickly because it breaks all the normal rules of punctuation that we use in English and every other computer language. (I don't know that MS invented it, it is just pervasive in their code, and it is where I usually encounter it)

All of that is not to say I completely disagree with your idea, it is attractive in a number of ways, I am just pointing out some tradeoffs (and putting the lie to your "no more arguing" ;))


I took part in consulting projects that decided on the style guide as the project infrastructure was designed.

It only applied to the source code for the project at hand.


Yeah, obviously but it's not "Standard". If I do that next thing will be "but I think we should change indent option X because it's better that way".

In the long run it would probably be a good thing but I'm not sure I'm ready to go through the massive flamewar that would be at first.

In the end I wouldn't mind this being handled at "language" level. Maybe even a flag in GCC that would warn/error on a coding style error. It would save everybody time, resources and probably a few friendships along the way.


It is a standard for the specific project.

Just a decision, like many other, that take place at the beginning of a project.


The Go Sublime plugin will go fmt your code on save:

https://github.com/DisposaBoy/GoSublime

It's nice not having to think about proper spacing anymore and just focusing on writing the code itself.


This was one of my favorite parts about jetbrains products. Auto cleanup right while you are coding. Push devs, kicking and screaming sometimes, into the pit of success.


The Go project provides similar functionality for most common editors (Emacs, Vim). The spf13-vim distribution supports this for Vim.


Go fmt isn’t without it’s detractors. People complain that go fmt isn’t customizable and that it puts braces where they don’t want them. Fools.

How would you feel if I left a comment calling you a fool for writing such a remark? Now realize you're giving that same feeling to every reader you're trying to convince.

It's far more effective to point out why someone is mistaken and leave it at that, as 'pg has demonstrated over the years.


If you find this kind of tone off-putting, whatever you do, don't read the scsh acknowledgments ( http://www.scsh.net/docu/html/man.html )!


That wasn't meant to be persuasive, though. Here's a more analogous example from that same author: http://www.paulgraham.com/thist.html


I don't think this should be taken hardly. A lot of people (from what I've seen) complain about go fmt doing things they don't like (bracing structure, indentation, etc.) For me it was no big deal since my bracing "standard" (what I did 90% of the time out of luck) is almost the same as go. And most people complaining just don't try to (ehem) go with it: once you are used to seeing your code neatly formatted automagically, always exactly the same, you start to see how neat it is. Also, being able to read other people's go code without hiccups is awesome.


I read it as tongue in cheek.

Think this is the first time I've read about someone being offended for being called a fool, maybe this is just a touchy subject for some people(not trying to be snarky)


Wasn't intended to offend. I'll reword that sentence. I do go on to explain why it's a mistake. It's really just that one word that seems to offend.


I'm sure Go puts the curly's in a few incorrect places. :-)

I would gladly trade that for never having to worry about it again. ask_two peopleForTheir_opinion any YOU'LL get 3_answers. Just pick one standard and get over it.

Someday there will be a billion lines of Go and it will all be formatted to the same standard.


`go vet` (checks correctness) and golint (https://github.com/golang/lint) are also extremely useful.

As a whole the toolchain makes working with Go code very convenient.


Was going to post this, agreed, those can really be useful while doing real refactoring.


Also, go run -race


> People complain that go fmt isn’t customizable and that it puts braces where they don’t want them.

I assume this is referring to putting opening braces on the next line.

IIRC, this has nothing to do with the `go fmt` tool - unlike in C, this is actually a syntax error in Go: http://play.golang.org/p/bn30UNkr1z

One of the reasons for this decision is because it helps enforce a truly context-free grammar for the language.

Ironically, the fact that Go has a nearly context-free grammar is what allows tools like `go fmt` and the obsolete `go fix` to make modifications to the code deterministically, with guarantees that it will not change the behavior of the code.


That is by far not the only way to do have a context-free grammar. Python for example also has a context-free grammar without semicolon insertion.


A) Python is not context-free; this is a common misconception: http://trevorjim.com/python-is-not-context-free/

B) No one feature of a grammar provides context-freedom. It's not meaningful to compare Go's grammar to another grammar; it's meaningful to compare Go's grammar as-is to the way it would be if it allowed both forms.

In this case, I believe the same-line braces rule is not strictly necessary by itself (they could have gotten a context-free grammar other ways), but this was (part of) one approach.


It is context free. Just because two tokens (INDENT, OUTDENT) are different to lex doesn't mean the grammar isn't context free.

The only reason same-line braces are required is semicolon insertion. There are other ways to express the grammar of a language without semicolons and remain context-free.


> There are other ways to express the grammar of a language without semicolons and remain context-free.

Yes, you could use s-expressions, for example. I never said that this was the only way; I just explained part of the reason for the choice.


No, there are other ways to express the exact same syntax with a context-free grammar, for example making newlines a significant token.


IMO that article doesn't really say anything interesting. There is no clear dividing line between the lexer, the parser, and semantic analysis. You have a great deal of freedom to move work between these phases, and what the grammar you're using at the parser level looks like can change drastically as a result.

If Python's lexer is not regular, it doesn't change the fact that the parser uses a context-free grammar over the resulting lexemes. Whether that's the right approach is an engineering tradeoff and nothing more.


You can even use gofmt to export variables that you want exported throughout the project. I wrote about it on this coderwall: https://coderwall.com/p/ds3iuw

edit: aha, the article did mention "gofmt -r"


This is nice, but I don't think it is refactoring.


The second half of the article is all about refactoring. Very similar to the refactor functionality provided by Eclipse & IntelliJ.


Maybe there are better examples, but removing parentheses and renaming a field are so trivial that I would not refer to them as refactoring.


While go fmt is great tool, it is no different than integrating indent or similar tool in the source control system.


Indent(1) is a textual tool while gofmt does full syntactic analysis. Among other things, indent(1) can't refactor code.


I just gave indent as a possible example, there are other tools.


'golang' would me more appropriate in the subj. I thought it was something generic


The command is go and it's argument is fmt.




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

Search: