Francesc (@francesc) is a member of the Go core team and a developer advocate for Google Cloud Platform. He’s a lover of programming languages, a master of technical instruction at Google, and one of the creators of the Go tour. This talk was inspired by another talk from Raquel Vélez at JSConf. Slides for this talk have been posted here.
Sourcegraph is building the next generation of programming collaboration tools for searching, exploring, and reviewing code. We attended GopherCon India to share how we use Go and learn from how others are using it, and were honored to coordinate the liveblog of the talks.
As a developer advocate on the Go team, Francesc has probably interacted with more Go programmers than almost anyone else in the world. From this unique vantage point, he has seen 5 general stages in the evolution of programmers working in Go.
These stages apply to how programmers progress through other languages, too. Understanding where you are in this evolution can help you figure out the most effective ways to improve and avoid common pitfalls that befall students of programming languages at every level.
Editor’s note: this post has interactive code snippets for each phase of this evolution. Clicking on any function name jumps you to the definition in code for further exploration. Scroll down to see them.
Here the 5 phases in the evolution of a Gopher:
- Phase 1 (the newcomer): You just learned the language. You’ve gone through a few tutorials or workshops, you understand basic syntax, and you can write short snippets of code.
- Phase 2 (the explorer): You can write a complete program, but don’t understand some more advanced language features like channels. You haven’t yet written a large project in Go.
- Phase 3 (the builder): You’re proficient in Go, you’re using Go in production to solve a specific and complete problem. You have a strong command of the common patterns and idioms in the language community. Go is a strong tool in your programming toolbelt.
- Phase 4 (the expert): You understand the design choices and motivations behind the language. You grok the philosophy of simplicity and composability.
- The advocate: You’re actively sharing your knowledge and understanding of the language with others. You’re a voice in the community, a participant on mailing lists and chatrooms, and you’re giving talks at conferences. Being an advocate is not really a separate stage, but a role you can fill at any of the other stages.
Phase 1: the newcomer
An interactive snippet from hello.go in the golang/example repository, which contains simple examples of small Go programs. Click around to explore the code.
An important skill newcomers should develop is learning how to ask questions. A lot of people new to the mailing list say things like, “Hey, this doesn’t work,” without providing enough context to enable others to understand and help fix their problem. At the opposite end of the spectrum are those who copy and paste hundreds of lines of code into a forum post and haven’t invested the time to come up with a focused example that illustrates their problem.
Also, you should rarely copy and paste code directly into the forum. Instead use the “share” button of the Go playground to link to snippets of code that others can edit and run directly in their browser.
Phase 2: the explorer
The explorer has written some small projects in Go, but still gets lost sometimes. They might not fully understand or know how to use more advanced language features like channels. They still have many things to learn, but know enough to build useful things. They are starting to get a sense of the potential of Go and are excited about what they’ll be able to build in the language.
Within the explorer phase, you typically go through two steps. First, you ascend to the Peak of Inflated Expectations. You think you can do everything in Go, but without really understanding or grokking the Go ethos yet. You are probably trying to apply the idioms and patterns you know from other languages in Go code, and you don’t yet have a strong sense of what constitutes idiomatic Go. You try to undertake tasks like “migrate framework X from language Y to Go”.
Following the Peak of Inflated Expectations is the Trough of Disillusionment. You miss feature X from language Y. You haven’t fully bought into idiomatic Go. You are still trying to write in the style of other programming languages and are getting frustrated. You may use the
unsafe packages a lot. This is not idiomatic Go. Idiomatic Go tends to avoid things that are too “magical”.
The Martini web framework is an example of a project that exemplifies the explorer phase. Martini was an early Go web framework that adopted a lot of concepts from Ruby web frameworks (like dependency injection). It received a lot of excitement from the community initially, but eventually had many issues around performance and debuggability. Jeremy Saenz (@codegangsta), the creator of Martini, responded constructively to feedback from the Go community and wrote another library called Negroni that follows more idiomatic Go conventions.
Interactive code snippet from the Martini web framework, an example of non-idiomatic Go. Note the dependency injection implemented via the reflect package.
Interactive code snippet demonstrating use of the Negroni library, an example of more idiomatic Go.
Many other languages rely heavily on third-party libraries to deliver core functionality like HTTP handling. One thing that distinguishes Go is the power of its standard library. If you think the Go standard library is not powerful enough to do what you want to do, you might be wrong. The Go standard library is incredibly powerful, and it’s worth reading through its code to learn the patterns of how it implements things.
An interactive snippet of the ListenAndServe method in the Go standard library. If you’ve written Go code, you’ve probably called this function many times, but have you bothered to see how it’s written? Go ahead and click around in the snippet above.
The disillusionment of the Trough of Disillusionment comes from the fact that you are still thinking in the patterns of other languages and you haven’t yet fully explored much of what Go offers. Here are some fun things you can do to avoid stalling and dive further into cool things you can do in the language.
go generate is a command that you can use to auto-generate Go code. You can use it in conjunction with metaprograms like jsonenums (a library to auto-generate JSON marshalling boilerplate code for enum types) to automate the writing of tedious code. The Go standard library has a great API for parsing the AST, which makes metaprogramming tools simple and easy to write. This is a point covered in 2 other talks at the conference (Practical Metaprogramming in Go and Embracing the Standard Library).
An interactive snippet showing how the jsonenums command is written.
Many people use Go for web services, but did you know that you can also create cool graphics in Go? Check out the OpenGL bindings in Go.
Interactive snippet illustrating use of Go OpenGL bindings to make a Gopher cube. Click a function or method name to explore.
Hackathons and challenges
You should also check out challenges and hackathons like the Gopher Gala and the Go Challenge. In the past, programmers from around the world have hacked together some really cool projects that you can take inspiration from.
Phase 3: the builder
Being a builder means you’ve been solving a lot of problems you care about in Go. New problems lead to new questions, and through the process of trial and failure, you’re going to learn what works and what doesn’t in the language. As a builder, you have a solid command of the idioms and patterns in the Go language. You’re able to work extremely quickly and effectively, and write readable, well-documented, and maintainable code.
A good way to develop mastery as a builder is to work on a large project. If you have an idea for a project yourself, you can go ahead and build it (provided you’ve checked that it doesn’t already exist). Most people may not have an idea for a big new project and should contribute to an existing project. Go has many large and heavily used projects such as Docker, Kubernetes, and Go itself. Take a look at the list.
Interactive snippet of code from Docker. Click on any function name to start exploring.
Builders should have a strong command of the tooling in the Go ecosystem, as these can really boost your productivity. You should look at
go test-race, and
You should use
go fmt, because it auto-formats your code according to the Go community style standard.
goimports does the same thing, but also adds missing imports.
goreturns does everything
goimports does, but also adds missing errors in return expressions, a common annoyance.
An important process to undertake at the builder stage is code review. The point of code review is not really to fix or find mistakes (that’s what tests are for). Code reviews are great for enforcing consistent coding style, improving the overall quality of the software, and improving your own skill as a developer through human feedback. Almost every large open-source project does code review for every change to code.
Here’s one example of learning through human feedback: The Go team at Google used to declare command-line flags outside of the main function. At GopherCon last year, Francesc met Peter Bourgon (@peterbourgon) from SoundCloud who told him that at SoundCloud, they declare all flags inside the main function so they don’t accidentally use flags outside the main function. Francesc now considers this best practice.
Phase 4: the expert
As an expert, you understand the philosophy of the language. You know when and when not to use language features. Jeremy Saenz, for example, gave a great talk at dotGo where he talked about when not to use interfaces.
An interactive code snippet from the standard library that uses channels. A great way to become an expert in Go is to understand the reasoning behind patterns in the standard library.
As an advocate, you share your knowledge and give talks about the lessons and best practices you’ve learned and developed. You should share what you like and also what you don’t like about Go. There are Go meetups around the world. Find the one nearest you.
You can be an advocate at any stage. Don’t wait until you become an expert in the language to make your voice heard. As you’re progressing through the different stages of learning Go, ask questions and give feedback on your experience. Be loud and don’t be shy about mentioning the things you don’t like. The conversations you have will help the community improve the way it does things and perhaps change the way you think about programming, too.
The main function of the popular
present command, which many Go users use to create slides. Many speakers have hacked present to customize it to their own needs.
Q: One of the features I miss is a good debugger in Go.
A: We’re working on it, and not just that but better monitoring tools in general that give you greater insight into what the program is doing when it’s running (like showing the state of all running goroutines). Look for it in Go 1.5.