Hacker News new | ask | show | jobs
by jgrahamc 4571 days ago
What is non-idiomatic about it?
3 comments

A mix of lint-y and style problems, and over-use of named returned parameters.

https://github.com/cloudflare/bm/blob/master/src/bm/bm.go#L4...

-- comment block should start with Dictionary.

https://github.com/cloudflare/bm/blob/master/src/bm/bm.go#L5...

-- comment should precede the declaration.

https://github.com/cloudflare/bm/blob/master/src/bm/bm.go#L6... and others

-- spurious newlines

https://github.com/cloudflare/bm/blob/master/src/bm/bm.go#L7...

-- needless named return parameters

https://github.com/cloudflare/bm/blob/master/src/bm/bm.go#L1...

https://github.com/cloudflare/bm/blob/master/src/bm/bm.go#L1...

https://github.com/cloudflare/bm/blob/master/src/bm/bm.go#L2...

(many others)

-- prefer early return or continue over if/else

https://github.com/cloudflare/bm/blob/master/src/bm/bm.go#L1...

-- more boilerplate due to the needless decision to use named return params

Happy to take a pull request from you for those improvements. We open sourced stuff partially so that we get feedback on the code, and I'm always happy to learn from others.
Named return parameters are unfortunate. Probably better to never use them unless you have to (like if you are "catching" a panic). Otherwise, I think you are nitpicking a bit.
I don't mind using named returns a lot--they can help to document, and sometimes they save you a declaration you were going to do in the method body anyway.

There are times they can be redundant (Sum(ints) does not need its return value named), or make the code less clear, or they indicate that you're trying to work around having overcomplicated methods by documenting them--I'm not saying always use them. But I don't try to avoid them.

That usage with recover would be to be able to set return parameters that might otherwise be returned as their zero values, correct?
Exactly. You can't return from the outer function in a defer, but you do have access to named return values. It's a bit of a kludge.
What's wrong with named return parameters?
http://golang.org/doc/effective_go.html#named-results

It's far more convenient looking at the function deceleration and knowing what comes and goes instead of hunting for return statements.

You should also consider organizing your repo to be `go get` compliant.

http://golang.org/doc/code.html#Organization

"go get" is kind of ok for trying out a new library quickly, but it's terrible for a real project.

Brad Fitzpatrick doesn't use it for Camlistore, instead he also does a Makefile-like system: https://github.com/bradfitz/camlistore

The sooner they deprecate the use of "go get", the better.

Brad is keeping a copy of all 3rd party libraries in https://github.com/bradfitz/camlistore/tree/master/third_par...

Is this the approach you recommend? I’ve never built a large go project, so I’m eager to learn what the best practices are.

I would not use Camlistore as an example for typical Go best-practices. Aside from the fact that >30% of the project (by Github's estimation) is written in various other languages, the opening comment on the Makefile reads, "The rest of this Makefile is mostly historical and should hopefully disappear over time."

Also, GP is conflating the issues of (1) fetching dependencies, (2) building a project, (3) installing the project. Makefiles aren't inherently evidence against "go get"; there is no reason that "go get" couldn't call "make" instead of "go build" (which it does).

The main reason that (almost) no pure Go projects have Makefiles anymore[0] is because they're frankly not needed. The standard Go build tools[1] are more than sufficient.

Don't take my word for it, though. Hop on #go-nuts on freenode and ask the guys there (many of whom are core contributors) what they think of Makefiles. They'll tell you the same thing that they told me over a year ago when I tried to advocate the use of Makefiles in pure Go projects.

[0] For what it's worth, before Go 1.0 came out, projects had Makefiles. The fact that Makefiles were a part of the standard build process and later removed should be a hint as to what the idiomatic Go approach is considered to be.

[1] "go get" isn't exactly a build tool in this sense; it's a convenience wrapper for cloning using git/hg/etc., followed by "go build" and "go install"

> Also, GP is conflating the issues of (1) fetching dependencies, (2) building a project, (3) installing the project. Makefiles aren't inherently evidence against "go get"; there is no reason that "go get" couldn't call "make" instead of "go build" (which it does).

Go get conflates those issues. It fetches dependencies, builds the project, and installs it.

You don't need Makefiles, you're right. You need a script that sets GOPATH and calls "go build".

The most important thing is to not depend on the whims of somebody else's repository. In the best case, they'll push an update and break your code for a while. In the worst case, they'll delete their repo; then you get to find your local copy, push it to github, and change all your source files to point to that.

Heaven help you if other people want to fork your project. Say I wrote "github.com/jff/bigproject", which depends on my package "github.com/jff/mypackage". Now, if Joe wants to fork the package and make a tweak, he also has to fork the main project and change all of its imports to point to github.com/joe/mypackage so he can compile and test it. Of course he can't very well push that, he'll have to revert the import changes again assuming I accept his pull request for mypackage. I've dealt with this in real practice when we had 3 people working on a project which imported 3 other packages. We were forever dealing with build failures and changed import paths and of course could hardly do a pull from one fork to another. It was hell.

Better to distribute the entire workspace, with src/ containing all the packages you need and nothing else.

Yes, that's what I recommend. I don't recommend a Makefile for a pure Go project, you really just need a shell script that sets GOPATH and calls "go build". That's what we do and it works well.
> you really just need a shell script that sets GOPATH

No. :|

The main problem is that one can't use "go get" to install it. There's no reason to have all the code in /src/bm.

(As pointed out elsewhere, there are style issues, but the lack of installability prevents me from even playing around with it).

EDIT: Just submitted a pull request - here's what I'm talking about: https://github.com/ChimeraCoder/bm

It's one package. It has no external repo dependencies. Do a git clone and get over yourself. As I've said elsewhere in the thread, "go get" is all fun and games until you try to make something real with it, then you realize that OOPS that guy deleted his repository and now nobody can build your code because you've tied your project to the continued existence of half a dozen external repositories.
It's one package with no external dependencies for now...
And it's one package on GitHub "for now" also... Tomorrow it might not be there, or be incompatible with its previous API.

But go get will hapilly try to use it...

Thanks. Merged that request.