January 29, 2013

Go is for Open Source

The Go programming language is built from the ground up to implicitly encourage Go projects to be open source. If you want your project not only to contribute to open source, but to encourage other people to write open source code, Go is a great language to choose.

Let's look at how Go does this. These first two points are overly obvious, but we should get them out of the way.

The language is open source

You can go look at the source code for the language, the compilers, and the build tools for the language. It's a fully open source project. Even though a lot of the work is being done by Google engineers, there are hundreds of names on the list of contributors of people who are not Google employees.

The standard library is open source

Want to see high quality example code? Look at the code in the standard library. It has been carefully reviewed to be of the best quality, and in canonical Go style. Reading the standard library is a great way to learn the best ways to use and write Go.


Ok, that's great, but what about all the code that isn't part of Go itself?
The design of Go really shows its embrace of open source in how third party code is used in day to day projects.

Go makes it trivial to use someone else's code in your project

Go has distributed version control built-in from the ground up. If you want to use a package from github, for example, you just specify the URL in the imports, as if it were a local package:

import (
    "bytes" // std lib package
    "github.com/fake/foo" // 3rd party package
)

You don't have to go find and download fake/foo from github and put it in a special directory or anything. Just run "go get github.com/fake/foo". Go will then download, build, and install the code, so that you can reference it... nicely stored in a directory defined by the URL, in this case $GOPATH/src/github.com/fake/foo. Go will even figure out what source control system is used on the other side so you don't have to (support for git, svn, mercurial, and bazaar).

What's even better is that the auto-download happens for anyone who calls "go get" on your code repository. No more giving long drawn-out installation instructions about getting half a dozen 3rd party libraries first. If someone wants your code, they type "go get path.to/your/code", and Go will download your code, and any remote imports you have (like the one for github above), any remote imports that code has, etc, and then builds everything.

The fact that this is available from the command line tools that come with the language makes it the de facto standard for how all Go code is written. There's no fragmentation in the community about how packages are stored, accessed, used, etc. This means zero overhead for using third party code, it's as easy to use as if it were built into the Go standard library.

Sharing code is the default

Like most scripting languages (and unlike many compiled languages), using source code from another project is the default way to use third party code in Go. Go creates a monolithic executable during its build, so there are no DLLs to create and distribute in the way you often see with other compiled languages. In theory you could distribute the compiled .a files from your project for other people to link to in their project, but this is not encouraged by the tooling, and I've personally never seen anyone do it.

All Go code uses the same style

Have you ever gone to read the source for a project you'd like to contribute to, and had your eyes cross over at the bizarre formatting the authors used? That almost never happens with Go. Go comes with a code formatting tool called gofmt that automatically formats Go code to the same style. The use of gofmt is strongly encouraged in the Go community, and nearly everyone uses it. Most text editors have an extension to automatically format your code with gofmt on save, so you don't even have to think about it. You never have to worry about having a poorly formatted library to work with... and in the very rare situation where you do, you can just run it through gofmt and you're good to go.

Easy cross platform support

Go makes it easy to support multiple platforms. The tooling can create native binaries for any popular operating system from the same source on a single machine. If you need platform-specific code, it's easy to specify code that only gets compiled for a single platform, by simply appending _<os> to a file name .e.g path_windows.go will only be compiled for builds targeting Windows.

Built-in documentation and testing

Go comes with a documentation generator that spits generates HTML or plain text from minimally formatted comments in the code. It also comes with a standard testing package that can run unit tests, performance benchmarks, and runnable example code. Because this is all available in the standard library and with the standard tools, nearly everyone uses it... which means it's easy to look at the documentation for any random Go package, and easy check if the tests pass, without having to go install some third party support tool. Because it's all standardized, several popular websites have popped up to automate generating (and hosting) the documentation for your project, and you can easily run continuous integration on your package, with only a single line in the setup script - "language: go".

Conclusion

Everything about Go encourages standardization and openness... which not only makes it possible to use other people's code, it makes it easy to use other people's code. I hope to see Go blossom as a language embraced by the open source community, as they discover the strengths that make it uniquely qualified for open source projects.

6 comments:

  1. Hello Nate,

    although your points are all valid, your article is somewhat one-sided. The lack of shared libraries (ie. only static linking) prohibits the use of LGPL'd libraries in some systems (unless you are an open source company anyway). This practically prevents any kind of copyleft license; as you can see, most (all?) of the licenses in the wild are BSD'ish. Now, BSD-type licenses are definitely open source, but ignoring the GPL-aspect entirely in your little list feels not right to me.

    So what if I 'go get' a package that go gets a package that go gets a package that is GPL?


    ReplyDelete
    Replies
    1. Hi Stefan.

      IMO the problem you describe is a limitation of the GPL, not Go. But that is a political discussion that is pointless to make here. (FWIW, Nate did say "Open Source" not "Free Software.")

      > So what if I 'go get' a package that go gets a package that go gets a package that is GPL?

      If my understanding of the GPL is correct, nothing. You only have a problem if you re-distribute a binary that was built using GPLed code.

      As I understand it, there's nothing wrong with writing programs that need GPL-licensed libraries to build them, nor is there a problem with distributing the source of those programs (not the GPL-licensed library). The go tool fetches all dependencies from their author's source repositories, so Go programmers rarely distribute other people's source code anyway.

      It's only if you're in the business of distributing binaries that you must do the due diligence and check the licenses of your dependencies. You can see a list of a Go package's dependencies with "go list -f '{{.Deps}}' package".

      Andrew

      Delete
    2. Andrew said pretty much exactly what I was thinking. One nice thing is that when someone uses go get, they're getting your dependencies directly from the people that published them. So you're not distributing them, per se.

      Yes, if you're a company that is distributing a binary built with Go that includes third party software, then you need to be careful about the code that it includes. That's true regardless of the language you use.

      Debating the merits of specific licenses is useless on this tiny blog, but my 2 cents is that GPL and LGPL are not terribly useful at this point, and I'd never use them for my own software.

      Delete
    3. I agree with what Andrew says, only I had expected exactly those statements in a blog-post that's titled "Go is for open source". It was also not my intention to start any political discussions here. Only, as someone who had to do that exact mentioned license checking in a commercial environment, I am painfully aware of the problems that arise from using open source licenses and I think that an article on the subject should talk about it. In that commercial environment I didn't have the luxury to simply say "I don't like the GPL, and I wouldn't use it", because it was not my choice to make.

      Delete
    4. It is a valid point, and honestly one I hadn't considered. I am glad you brought it up, and definitely would have been a good addition to the post. I'm glad the comments are here to make up for the missing information.

      Delete
  2. @Stefan

    LGPL was a workaround, even the FSF recommend GPL instead of LGPL.

    In some special cases, FSF recommend non-copyleft license. The VP8 codec for instance, releasing it under BSD allow more people to have the codec and as a result we have a very popular open-source codec.

    If you wan't the benefits of LGPL you could use other licenses (MPL 2.0 is one) that protect your library and still allow for closed-source distribution (even on static-linked files).

    ReplyDelete