The Go Blog

Toward Go 2

13 July 2017

Introduction

[This is the text of my talk today at Gophercon 2017, asking for the entire Go community's help as we discuss and plan Go 2. We will add a link to the video when it becomes available.]

On September 25, 2007, after Rob Pike, Robert Griesemer, and Ken Thompson had been discussing a new programming language for a few days, Rob suggested the name “Go.”

The next year, Ian Lance Taylor and I joined the team, and together the five of us built two compilers and a standard library, leading up to the open-source release on November 10, 2009.

For the next two years, with the help of the new Go open source community, we experimented with changes large and small, refining Go and leading to the plan for Go 1, proposed on October 5, 2011.

With more help from the Go community, we revised and implemented that plan, eventually releasing Go 1 on March 28, 2012.

The release of Go 1 marked the culmination of nearly five years of creative, frenetic effort that took us from a name and a list of ideas to a stable, production language. It also marked an explicit shift from change and churn to stability.

In the years leading to Go 1, we changed Go and broke everyone's Go programs nearly every week. We understood that this was keeping Go from use in production settings, where programs could not be rewritten weekly to keep up with language changes. As the blog post announcing Go 1 says, the driving motivation was to provide a stable foundation for creating reliable products, projects, and publications (blogs, tutorials, conference talks, and books), to make users confident that their programs would continue to compile and run without change for years to come.

After Go 1 was released, we knew that we needed to spend time using Go in the production environments it was designed for. We shifted explicitly away from making language changes toward using Go in our own projects and improving the implementation: we ported Go to many new systems, we rewrote nearly every performance-critical piece to make Go run more efficiently, and we added key tools like the race detector.

Now we have five years of experience using Go to build large, production-quality systems. We have developed a sense of what works and what does not. Now it is time to begin the next step in Go's evolution and growth, to plan the future of Go. I'm here today to ask all of you in the Go community, whether you're in the audience at GopherCon or watching on video or reading the Go blog later today, to work with us as we plan and implement Go 2.

In the rest of this talk, I'm going to explain our goals for Go 2; our constraints and limitations; the overall process; the importance of writing about our experiences using Go, especially as they relate to problems we might try to solve; the possible kinds of solutions; how we will deliver Go 2; and how all of you can help.

Goals

The goals we have for Go today are the same as in 2007. We want to make programmers more effective at managing two kinds of scale: production scale, especially concurrent systems interacting with many other servers, exemplified today by cloud software; and development scale, especially large codebases worked on by many engineers coordinating only loosely, exemplified today by modern open-source development.

These kinds of scale show up at companies of all sizes. Even a five-person startup may use large cloud-based API services provided by other companies and use more open-source software than software they write themselves. Production scale and development scale are just as relevant at that startup as they are at Google.

Our goal for Go 2 is to fix the most significant ways Go fails to scale.

(For more about these goals, see Rob Pike's 2012 article “Go at Google: Language Design in the Service of Software Engineering” and my GopherCon 2015 talk “Go, Open Source, Community.”)

Constraints

The goals for Go have not changed since the beginning, but the constraints on Go certainly have. The most important constraint is existing Go usage. We estimate that there are at least half a million Go developers worldwide, which means there are millions of Go source files and at least a billion of lines of Go code. Those programmers and that source code represent Go's success, but they are also the main constraint on Go 2.

Go 2 must bring along all those developers. We must ask them to unlearn old habits and learn new ones only when the reward is great. For example, before Go 1, the method implemented by error types was named String. In Go 1, we renamed it Error, to distinguish error types from other types that can format themselves. The other day I was implementing an error type, and without thinking I named its method String instead of Error, which of course did not compile. After five years I still have not completely unlearned the old way. That kind of clarifying renaming was an important change to make in Go 1 but would be too disruptive for Go 2 without a very good reason.

Go 2 must also bring along all the existing Go 1 source code. We must not split the Go ecosystem. Mixed programs, in which packages written in Go 2 import packages written in Go 1 and vice versa, must work effortlessly during a transition period of multiple years. We'll have to figure out exactly how to do that; automated tooling like go fix will certainly play a part.

To minimize disruption, each change will require careful thought, planning, and tooling, which in turn limits the number of changes we can make. Maybe we can do two or three, certainly not more than five.

I'm not counting minor housekeeping changes like maybe allowing identifiers in more spoken languages or adding binary integer literals. Minor changes like these are also important, but they are easier to get right. I'm focusing today on possible major changes, such as additional support for error handling, or introducing immutable or read-only values, or adding some form of generics, or other important topics not yet suggested. We can do only a few of those major changes. We will have to choose carefully.

Process

That raises an important question. What is the process for developing Go?

In the early days of Go, when there were just five of us, we worked in a pair of adjacent shared offices separated by a glass wall. It was easy to pull everyone into one office to discuss some problem and then go back to our desks to implement a solution. When some wrinkle arose during the implementation, it was easy to gather everyone again. Rob and Robert's office had a small couch and a whiteboard, so typically one of us went in and started writing an example on the board. Usually by the time the example was up, everyone else had reached a good stopping point in their own work and was ready to sit down and discuss it. That informality obviously doesn't scale to the global Go community of today.

Part of the work since the open-source release of Go has been porting our informal process into the more formal world of mailing lists and issue trackers and half a million users, but I don't think we've ever explicitly described our overall process. It's possible we never consciously thought about it. Looking back, though, I think this is the basic outline of our work on Go, the process we've been following since the first prototype was running.

Step 1 is to use Go, to accumulate experience with it.

Step 2 is to identify a problem with Go that might need solving and to articulate it, to explain it to others, to write it down.

Step 3 is to propose a solution to that problem, discuss it with others, and revise the solution based on that discussion.

Step 4 is to implement the solution, evaluate it, and refine it based on that evaluation.

Finally, step 5 is to ship the solution, adding it to the language, or the library, or the set of tools that people use from day to day.

The same person does not have to do all these steps for a particular change. In fact, usually many people collaborate on any given step, and many solutions may be proposed for a single problem. Also, at any point we may realize we don’t want to go further with a particular idea and circle back to an earlier step.

Although I don't believe we've ever talked about this process as a whole, we have explained parts of it. In 2012, when we released Go 1 and said that it was time now to use Go and stop changing it, we were explaining step 1. In 2015, when we introduced the Go change proposal process, we were explaining steps 3, 4, and 5. But we've never explained step 2 in detail, so I'd like to do that now.

(For more about the development of Go 1 and the shift away from language changes, see Rob Pike and Andrew Gerrand's OSCON 2012 talk “The Path to Go 1.” For more about the proposal process, see Andrew Gerrand's GopherCon 2015 talk “How Go was Made” and the proposal process documentation.)

Explaining Problems

There are two parts to explaining a problem. The first part—the easier part—is stating exactly what the problem is. We developers are decently good at this. After all, every test we write is a statement of a problem to be solved, in language so precise that even a computer can understand it. The second part—the harder part—is describing the significance of the problem well enough that everyone can understand why we should spend time solving it and maintaining a solution. In contrast to stating a problem precisely, we don't need to describe a problem's significance very often, and we're not nearly as good at it. Computers never ask us “why is this test case important? Are you sure this is the problem you need to solve? Is solving this problem the most important thing you can be doing?” Maybe they will someday, but not today.

Let's look at an old example from 2011. Here is what I wrote about renaming os.Error to error.Value while we were planning Go 1.

It begins with a precise, one-line statement of the problem: in very low-level libraries everything imports "os" for os.Error. Then there are five lines, which I've underlined here, devoted to describing the significance of the problem: the packages that "os" uses cannot themselves present errors in their APIs, and other packages depend on "os" for reasons having nothing to do with operating system services.

Do these five lines convince you that this problem is significant? It depends on how well you can fill in the context I've left out: being understood requires anticipating what others need to know. For my audience at the time—the ten other people on the Go team at Google who were reading that document—those fifty words were enough. To present the same problem to the audience at GothamGo last fall—an audience with much more varied backgrounds and areas of expertise—I needed to provide more context, and I used about two hundred words, along with real code examples and a diagram. It is a fact of today's worldwide Go community that describing the significance of any problem requires adding context, especially illustrated by concrete examples, that you would leave out when talking to coworkers.

Convincing others that a problem is significant is an essential step. When a problem appears insignificant, almost every solution will seem too expensive. But for a significant problem, there are usually many solutions of reasonable cost. When we disagree about whether to adopt a particular solution, we're often actually disagreeing about the significance of the problem being solved. This is so important that I want to look at two recent examples that show this clearly, at least in hindsight.

Example: Leap seconds

My first example is about time.

Suppose you want to time how long an event takes. You write down the start time, run the event, write down the end time, and then subtract the start time from the end time. If the event took ten milliseconds, the subtraction gives a result of ten milliseconds, perhaps plus or minus a small measurement error.

start := time.Now()       // 3:04:05.000
event()
end := time.Now()         // 3:04:05.010

elapsed := end.Sub(start) // 10 ms

This obvious procedure can fail during a leap second. When our clocks are not quite in sync with the daily rotation of the Earth, a leap second—officially 11:59pm and 60 seconds—is inserted just before midnight. Unlike leap years, leap seconds follow no predictable pattern, which makes them hard to fit into programs and APIs. Instead of trying to represent the occasional 61-second minute, operating systems typically implement a leap second by turning the clock back one second just before what would have been midnight, so that 11:59pm and 59 seconds happens twice. This clock reset makes time appear to move backward, so that our ten-millisecond event might be timed as taking negative 990 milliseconds.

start := time.Now()       // 11:59:59.995
event()
end := time.Now()         // 11:59:59.005 (really 11:59:60.005)

elapsed := end.Sub(start) // –990 ms

Because the time-of-day clock is inaccurate for timing events across clock resets like this, operating systems now provide a second clock, the monotonic clock, which has no absolute meaning but counts seconds and is never reset.

Except during the odd clock reset, the monotonic clock is no better than the time-of-day clock, and the time-of-day clock has the added benefit of being useful for telling time, so for simplicity Go 1’s time APIs expose only the time-of-day clock.

In October 2015, a bug report noted that Go programs could not time events correctly across clock resets, especially a typical leap second. The suggested fix was also the original issue title: “add a new API to access a monotonic clock source.” I argued that this problem was not significant enough to justify new API. A few months earlier, for the mid-2015 leap second, Akamai, Amazon, and Google had slowed their clocks a tiny amount for the entire day, absorbing the extra second without turning their clocks backward. It seemed like eventual widespread adoption of this “leap smear” approach would eliminate leap-second clock resets as a problem on production systems. In contrast, adding new API to Go would add new problems: we would have to explain the two kinds of clocks, educate users about when to use each, and convert many lines of existing code, all for an issue that rarely occurred and might plausibly go away on its own.

We did what we always do when there's a problem without a clear solution: we waited. Waiting gives us more time to add experience and understanding of the problem and also more time to find a good solution. In this case, waiting added to our understanding of the significance of the problem, in the form of a thankfully minor outage at Cloudflare. Their Go code timed DNS requests during the end-of-2016 leap second as taking around negative 990 milliseconds, which caused simultaneous panics across their servers, breaking 0.2% of DNS queries at peak.

Cloudflare is exactly the kind of cloud system Go was intended for, and they had a production outage based on Go not being able to time events correctly. Then, and this is the key point, Cloudflare reported their experience in a blog post by John Graham-Cumming titled “How and why the leap second affected Cloudflare DNS.” By sharing concrete details of their experience with Go in production, John and Cloudflare helped us understand that the problem of accurate timing across leap second clock resets was too significant to leave unfixed. Two months after that article was published, we had designed and implemented a solution that will ship in Go 1.9 (and in fact we did it with no new API).

Example: Alias declarations

My second example is support for alias declarations in Go.

Over the past few years, Google has established a team focused on large-scale code changes, meaning API migration and bug fixes applied across our codebase of millions of source files and billions of lines of code written in C++, Go, Java, Python, and other languages. One thing I've learned from that team's work is the importance, when changing an API from using one name to another, of being able to update client code in multiple steps, not all at once. To do this, it must be possible to write a declaration forwarding uses of the old name to the new name. C++ has #define, typedef, and using declarations to enable this forwarding, but Go has nothing. Of course, one of Go's goals is to scale well to large codebases, and as the amount of Go code at Google grew, it became clear both that we needed some kind of forwarding mechanism and also that other projects and companies would run into this problem as their Go codebases grew.

In March 2016, I started talking with Robert Griesemer and Rob Pike about how Go might handle gradual codebase updates, and we arrived at alias declarations, which are exactly the needed forwarding mechanism. At this point, I felt very good about the way Go was evolving. We'd talked about aliases since the early days of Go—in fact, the first spec draft has an example using alias declarations—but each time we'd discussed aliases, and later type aliases, we had no clear use case for them, so we left them out. Now we were proposing to add aliases not because they were an elegant concept but because they solved a significant practical problem with Go meeting its goal of scalable software development. I hoped this would serve as a model for future changes to Go.

Later in the spring, Robert and Rob wrote a proposal, and Robert presented it in a Gophercon 2016 lightning talk. The next few months did not go smoothly, and they were definitely not a model for future changes to Go. One of the many lessons we learned was the importance of describing the significance of a problem.

A minute ago, I explained the problem to you, giving some background about how it can arise and why, but with no concrete examples that might help you evaluate whether the problem might affect you at some point. Last summer’s proposal and the lightning talk gave an abstract example, involving packages C, L, L1, and C1 through Cn, but no concrete examples that developers could relate to. As a result, most of the feedback from the community was based on the idea that aliases only solved a problem for Google, not for everyone else.

Just as we at Google did not at first understand the significance of handling leap second time resets correctly, we did not effectively convey to the broader Go community the significance of handling gradual code migration and repair during large-scale changes.

In the fall we started over. I gave a talk and wrote an article presenting the problem using multiple concrete examples drawn from open source codebases, showing how this problem arises everywhere, not just inside Google. Now that more people understood the problem and could see its significance, we had a productive discussion about what kind of solution would be best. The outcome is that type aliases will be included in Go 1.9 and will help Go scale to ever-larger codebases.

Experience reports

The lesson here is that it is difficult but essential to describe the significance of a problem in a way that someone working in a different environment can understand. To discuss major changes to Go as a community, we will need to pay particular attention to describing the significance of any problem we want to solve. The clearest way to do that is by showing how the problem affects real programs and real production systems, like in Cloudflare's blog post and in my refactoring article.

Experience reports like these turn an abstract problem into a concrete one and help us understand its significance. They also serve as test cases: any proposed solution can be evaluated by examining its effect on the actual, real-world problems the reports describe.

For example, I've been examining generics recently, but I don't have in my mind a clear picture of the detailed, concrete problems that Go users need generics to solve. As a result, I can't answer a design question like whether to support generic methods, which is to say methods that are parameterized separately from the receiver. If we had a large set of real-world use cases, we could begin to answer a question like this by examining the significant ones.

As another example, I’ve seen proposals to extend the error interface in various ways, but I haven't seen any experience reports showing how large Go programs attempt to understand and handle errors at all, much less showing how the current error interface hinders those attempts. These reports would help us all better understand the details and significance of the problem, which we must do before solving it.

I could go on. Every major potential change to Go should be motivated by one or more experience reports documenting how people use Go today and why that's not working well enough. For the obvious major changes we might consider for Go, I'm not aware of many such reports, especially not reports illustrated with real-world examples.

These reports are the raw material for the Go 2 proposal process, and we need all of you to write them, to help us understand your experiences with Go. There are half a million of you, working in a broad range of environments, and not that many of us. Write a post on your own blog, or write a Medium post, or write a Github Gist (add a .md file extension for Markdown), or write a Google doc, or use any other publishing mechanism you like. After you've posted, please add the post to our new wiki page, golang.org/wiki/ExperienceReports.

Solutions

Now that we know how we're going to identify and explain problems that need to be solved, I want to note briefly that not all problems are best solved by language changes, and that's fine.

One problem we might want to solve is that computers can often compute additional results during basic arithmetic operations, but Go does not provide direct access to those results. In 2013, Robert proposed that we might extend the idea of two-result (“comma-ok”) expressions to basic arithmetic. For example, if x and y are, say, uint32 values, lo, hi = x * y would return not only the usual low 32 bits but also the high 32 bits of the product. This problem didn't seem particularly significant, so we recorded the potential solution but didn't implement it. We waited.

More recently, we designed for Go 1.9 a math/bits package that contains various bit manipulation functions:

package bits // import "math/bits"

func LeadingZeros32(x uint32) int
func Len32(x uint32) int
func OnesCount32(x uint32) int
func Reverse32(x uint32) uint32
func ReverseBytes32(x uint32) uint32
func RotateLeft32(x uint32, k int) uint32
func TrailingZeros32(x uint32) int
...

The package has good Go implementations of each function, but the compilers also substitute special hardware instructions when available. Based on this experience with math/bits, both Robert and I now believe that making the additional arithmetic results available by changing the language is unwise, and that instead we should define appropriate functions in a package like math/bits. Here the best solution is a library change, not a language change.

A different problem we might have wanted to solve, after Go 1.0, was the fact that goroutines and shared memory make it too easy to introduce races into Go programs, causing crashes and other misbehavior in production. The language-based solution would have been to find some way to disallow data races, to make it impossible to write or at least to compile a program with a data race. How to fit that into a language like Go is still an open question in the programming language world. Instead we added a tool to the main distribution and made it trivial to use: that tool, the race detector, has become an indispensible part of the Go experience. Here the best solution was a runtime and tooling change, not a language change.

There will be language changes as well, of course, but not all problems are best solved in the language.

Shipping Go 2

Finally, how will we ship and deliver Go 2?

I think the best plan would be to ship the backwards-compatible parts of Go 2 incrementally, feature by feature, as part of the Go 1 release sequence. This has a few important properties. First, it keeps the Go 1 releases on the usual schedule, to continue the timely bug fixes and improvements that users now depend on. Second, it avoids splitting development effort between Go 1 and Go 2. Third, it avoids divergence between Go 1 and Go 2, to ease everyone's eventual migration. Fourth, it allows us to focus on and deliver one change at a time, which should help maintain quality. Fifth, it will encourage us to design features to be backwards-compatible.

We will need time to discuss and plan before any changes start landing in Go 1 releases, but it seems plausible to me that we might start seeing minor changes about a year from now, for Go 1.12 or so. That also gives us time to land package management support first.

Once all the backwards-compatible work is done, say in Go 1.20, then we can make the backwards-incompatible changes in Go 2.0. If there turn out to be no backwards-incompatible changes, maybe we just declare that Go 1.20 is Go 2.0. Either way, at that point we will transition from working on the Go 1.X release sequence to working on the Go 2.X sequence, perhaps with an extended support window for the final Go 1.X release.

This is all a bit speculative, and the specific release numbers I just mentioned are placeholders for ballpark estimates, but I want to make clear that we're not abandoning Go 1, and that in fact we will bring Go 1 along to the greatest extent possible.

Help Wanted

We need your help.

The conversation for Go 2 starts today, and it's one that will happen in the open, in public forums like the mailing list and the issue tracker. Please help us at every step along the way.

Today, what we need most is experience reports. Please tell us how Go is working for you, and more importantly not working for you. Write a blog post, include real examples, concrete detail, and real experience. And link it on our wiki page. That's how we'll start talking about what we, the Go community, might want to change about Go.

Thank you.

By Russ Cox

Introducing the Developer Experience Working Group

10 April 2017

Over the last several years, Go's audience has shifted from early adopters to mainstream users. Today, our users come from a wide variety of backgrounds, experiences, and expectations. The needs of users are growing faster than the Go project can currently address them. To streamline the experience for first-time Go users, we've created the Developer eXperience Working Group (DXWG).

For the next three months, this group will work together on delivering:

  • improvements to the Go installation experience
  • better guidelines to help new users
  • guides on tooling and developer environments (editors and IDEs)
  • running user studies to systematically analyze and measure friction points
  • improvements to the Go Tour and Go Playground

A secondary goal of the working group is to better understand how to involve the Go community in charting Go’s future. We hope that working groups – Go team members working alongside community members – will help Go scale its leadership and address user needs. We’ll learn from this experience and iterate.

The initial members of the working group are: Carmen Andoh, Chris Broadfoot, Francesc Campoy, Jaana Burcu Dogan, Steve Francia, Jess Frazelle, Bill Kennedy, Katrina Owen, Natalie Pistunovich, Mat Ryer, Dmitri Shuralyov.

We are looking for additional people to help with contributing code, writing documentation, sharing feedback and experiences (user stories), reviewing contributions, and more. If you are interested in any of our current areas of focus, please join us on the #devexp channel on the Gophers Slack and subscribe to the golang-devexp mailing list.

By The Developer Experience Working Group

HTTP/2 Server Push

24 March 2017

Introduction

HTTP/2 is designed to address many of the failings of HTTP/1.x. Modern web pages use many resources: HTML, stylesheets, scripts, images, and so on. In HTTP/1.x, each of these resources must be requested explicitly. This can be a slow process. The browser starts by fetching the HTML, then learns of more resources incrementally as it parses and evaluates the page. Since the server must wait for the browser to make each request, the network is often idle and underutilized.

To improve latency, HTTP/2 introduced server push, which allows the server to push resources to the browser before they are explicitly requested. A server often knows many of the additional resources a page will need and can start pushing those resources as it responds to the initial request. This allows the server to fully utilize an otherwise idle network and improve page load times.

At the protocol level, HTTP/2 server push is driven by PUSH_PROMISE frames. A PUSH_PROMISE describes a request that the server predicts the browser will make in the near future. As soon as the browser receives a PUSH_PROMISE, it knows that the server will deliver the resource. If the browser later discovers that it needs this resource, it will wait for the push to complete rather than sending a new request. This reduces the time the browser spends waiting on the network.

Server Push in net/http

Go 1.8 introduced support for pushing responses from an http.Server. This feature is available if the running server is an HTTP/2 server and the incoming connection uses HTTP/2. In any HTTP handler, you can assert if the http.ResponseWriter supports server push by checking if it implements the new http.Pusher interface.

For example, if the server knows that app.js will be required to render the page, the handler can initiate a push if http.Pusher is available:

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if pusher, ok := w.(http.Pusher); ok {
            // Push is supported.
            if err := pusher.Push("/app.js", nil); err != nil {
                log.Printf("Failed to push: %v", err)
            }
        }
        // ...
    })

The Push call creates a synthetic request for /app.js, synthesizes that request into a PUSH_PROMISE frame, then forwards the synthetic request to the server's request handler, which will generate the pushed response. The second argument to Push specifies additional headers to include in the PUSH_PROMISE. For example, if the response to /app.js varies on Accept-Encoding, then the PUSH_PROMISE should include an Accept-Encoding value:

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if pusher, ok := w.(http.Pusher); ok {
            // Push is supported.
            options := &http.PushOptions{
                Header: http.Header{
                    "Accept-Encoding": r.Header["Accept-Encoding"],
                },
            }
            if err := pusher.Push("/app.js", options); err != nil {
                log.Printf("Failed to push: %v", err)
            }
        }
        // ...
    })

A fully working example is available at:

$ go get golang.org/x/blog/content/h2push/server

If you run the server and load https://localhost:8080, your browser's developer tools should show that app.js and style.css were pushed by the server.

Start Your Pushes Before You Respond

It's a good idea to call the Push method before sending any bytes of the response. Otherwise it is possible to accidentally generate duplicate responses. For example, suppose you write part of an HTML response:

<html>
<head>
    <link rel="stylesheet" href="a.css">...

Then you call Push("a.css", nil). The browser may parse this fragment of HTML before it receives your PUSH_PROMISE, in which case the browser will send a request for a.css in addition to receiving your PUSH_PROMISE. Now the server will generate two responses for a.css. Calling Push before writing the response avoids this possibility entirely.

When To Use Server Push

Consider using server push any time your network link is idle. Just finished sending the HTML for your web app? Don't waste time waiting, start pushing the resources your client will need. Are you inlining resources into your HTML file to reduce latency? Instead of inlining, try pushing. Redirects are another good time to use push because there is almost always a wasted round trip while the client follows the redirect. There are many possible scenarios for using push -- we are only getting started.

We would be remiss if we did not mention a few caveats. First, you can only push resources your server is authoritative for -- this means you cannot push resources that are hosted on third-party servers or CDNs. Second, don't push resources unless you are confident they are actually needed by the client, otherwise your push wastes bandwidth. A corollary is to avoid pushing resources when it's likely that the client already has those resources cached. Third, the naive approach of pushing all resources on your page often makes performance worse. When in doubt, measure.

The following links make for good supplemental reading:

Conclusion

With Go 1.8, the standard library provides out-of-the-box support for HTTP/2 Server Push, giving you more flexibility to optimize your web applications.

Go to our HTTP/2 Server Push demo page to see it in action.

By Jaana Burcu Dogan, Tom Bergan

Go 2016 Survey Results

6 March 2017

Thank you

This post summarizes the result of our December 2016 user survey along with our commentary and insights. We are grateful to everyone who provided their feedback through the survey to help shape the future of Go.

Programming background

Of the 3,595 survey respondents, 89% said they program in Go at work or outside of work, with 39% using Go both at home and at work, 27% using Go only at home, and 23% using Go only at work.

We asked about the areas in which people work. 63% said they work in web development, but only 9% listed web development alone. In fact, 77% chose two or more areas, and 53% chose three or more.

We also asked about the kinds of programs people write in Go. 63% of respondents write command-line programs, 60% write API or RPC services, and 52% write web services. Like in the previous question, most made multiple choices, with 85% choosing two or more and 72% choosing three or more.

We asked about people’s expertise and preference among programming languages. Unsurprisingly, Go ranked highest among respondents’ first choices in both expertise (26%) and preference (62%). With Go excluded, the top five first choices for language expertise were Python (18%), Java (17%), JavaScript (13%), C (11%), and PHP (8%); and the top five first choices for language preference were Python (22%), JavaScript (10%), C (9%), Java (9%), and Ruby (7%). Go is clearly attracting many programmers from dynamic languages.

The following apply to me: (multiple choice) 2,386 (66%) I program in Go outside of work 2,235 (62%) I program at work in Go 2,004 (56%) I program at work in another language 618 (17%) I manage a programming team 337  (9%) I am a student 78  (2%) Other 10  (0%) No response

Reading the data: This question was “multiple choice,” so the percentages add up to well over 100%. All graphs in this post show both the total count and the corresponding percentage of the 3,595 surveys completed.

I work in the following areas: (multiple choice) 2,272 (63%) Web development 1,359 (38%) Systems programming 1,251 (35%) DevOps 1,169 (33%) Network programming 1,006 (28%) Databases 533 (15%) Mobile 490 (14%) Desktop/GUI applications 457 (13%) Security 435 (12%) Data Science 417 (12%) Finance/Commerce 394 (11%) Embedded devices/Internet of Things 379 (11%) Academic/Scientific/Numeric 228  (6%) Gaming 238  (7%) Other 74  (2%) No response

I've used Go for: (single choice) 432 (12%) Less than 3 months 1,009 (28%) 3 - 12 months 829 (23%) 13 - 24 months 903 (25%) 2 - 4 years 321  (9%) 4+ years 77  (2%) I've never used Go 24  (1%) No response

I write the following in Go: (multiple choice) 2,247 (63%) A runnable/interactive program (CLI) 2,174 (60%) API/RPC services (returning non-HTML) 1,886 (52%) Web services (returning HTML) 1,583 (44%) Agents and daemons (e.g, monitoring) 1,417 (39%) Libraries or Frameworks 1,209 (34%) Data processing (pipeline, aggregation) 1,120 (31%) Automation/scripts (e.g, deployment, configuration management) 107  (3%) I don't write in Go 137  (4%) Other 45  (1%) No response

I write in Go: (single choice) 1,567 (44%) As part of my daily routine 1,054 (29%) Weekly 486 (14%) Infrequently 368 (10%) Monthly 77  (2%) I've never written in Go 43  (1%) No response

Rank the following languages in terms of your expertise: (ordered choice, up to 5) 3,111 (26, 26, 19, 10, 5%) Go 2,048 (8, 15, 14, 11, 8%) JavaScript 1,896 (12, 12, 10, 10, 7%) Python 1,618 (13, 8, 8, 8, 8%) Java 1,512 (8, 8, 9, 9, 7%) C 1,064 (2, 4, 7, 8, 8%) Bash 1,039 (5, 5, 7, 6, 6%) C++ 830 (6, 4, 4, 5, 4%) PHP 668 (5, 4, 3, 4, 3%) Ruby 622 (5, 3, 3, 4, 3%) C# 294 (2, 1, 2, 2, 2%) Perl 184 (1, 1, 1, 1, 1%) Scala 156 (0, 0, 1, 1, 2%) Rust 142 (0, 0, 1, 1, 1%) Lua 136 (0, 0, 0, 1, 2%) Haskell 94 (0, 0, 0, 1, 1%) R 93 (0, 0, 0, 1, 1%) Clojure 72 (0, 0, 0, 0, 1%) Erlang 18 (0, 0, 0, 0, 0%) Julia 499 (2, 3, 3, 3, 3%) Other 134 (3.7%) No response

Reading the data: This question was “ordered choice.” The first, second, third, fourth, and fifth choices are displayed as progressively lighter sections of the bars. The total count shown next to the bar is for all choices; the percentage list shows how the choices are divided.

Rank the following languages in terms of your preference: (ordered choice, up to 5) 3,248 (62, 19, 6, 2, 1%) Go 1,796 (7, 17, 12, 9, 5%) Python 1,482 (3, 9, 13, 10, 8%) JavaScript 1,235 (2, 8, 9, 9, 6%) C 1,167 (3, 7, 8, 7, 7%) Java 809 (2, 4, 6, 6, 5%) C++ 647 (1, 3, 5, 5, 5%) Bash 563 (3, 5, 4, 3, 2%) Ruby 557 (2, 4, 4, 3, 2%) C# 475 (2, 4, 3, 3, 2%) Rust 449 (1, 2, 3, 3, 3%) PHP 278 (1, 2, 2, 2, 1%) Haskell 215 (1, 1, 1, 1, 1%) Perl 214 (1, 1, 1, 1, 1%) Scala 178 (0, 1, 2, 2, 1%) Lua 168 (0, 1, 1, 1, 1%) Erlang 156 (1, 1, 1, 1, 1%) Clojure 79 (0, 0, 0, 1, 1%) R 43 (0, 0, 0, 0, 0%) Julia 507 (3, 4, 4, 2, 1%) Other 166 (4.6%) No response

Go usage

Users are overwhelmingly happy with Go: they agree that they would recommend Go to others by a ratio of 19:1, that they’d prefer to use Go for their next project (14:1), and that Go is working well for their teams (18:1). Fewer users agree that Go is critical to their company’s success (2.5:1).

When asked what they like most about Go, users most commonly mentioned Go’s simplicity, ease of use, concurrency features, and performance. When asked what changes would most improve Go, users most commonly mentioned generics, package versioning, and dependency management. Other popular responses were GUIs, debugging, and error handling.

When asked about the biggest challenges to their own personal use of Go, users mentioned many of the technical changes suggested in the previous question. The most common themes in the non-technical challenges were convincing others to use Go and communicating the value of Go to others, including management. Another common theme was learning Go or helping others learn, including finding documentation like getting-started walkthroughs, tutorials, examples, and best practices.

Some representative common feedback, paraphrased for confidentiality:

“The documentation is not clear enough for beginners. It needs more examples and often assumes experience with other languages and various computer science topics.”

“I want to use Go at work but struggle to convince my team to even try Go.”

“I can’t get management approval to use Go; they don’t see its value and worry about adoption and finding developers.”

We appreciate the feedback given to identify these challenges faced by our users and community. In 2017 we are focusing on addressing these issues and hope to make as many significant improvements as we can. We welcome suggestions and contributions from the community in making these challenges into strengths for Go.

To what extent do you agree or disagree with the following statements: (strongly disagree, disagree, somewhat disagree, neutral, somewhat agree, agree, strongly agree) 3,250 (2, 1, 1, 2, 5, 21, 57%) I would recommend using Go to others (19:1) 3,219 (3, 1, 2, 4, 8, 19, 52%) I would prefer to use Go for my next new project (14:1) 2,325 (1, 1, 1, 7, 8, 25, 22%) Go is working well for my team. (18:1) 2,336 (4, 7, 3, 14, 12, 12, 12%) Go is critical to my company's success. (2.5:1)

Reading the data: This question asked how strongly the respondent agreed or disagreed with the statement. The responses for each statement are displayed as sections of a single bar, from “strongly disagree” in deep red on the left end to “strongly agree” in deep blue on the right end. The bars use the same scale as the rest of the graphs, so they can (and do, especially later in the survey) vary in overall length due to lack of responses. The ratio after the text compares the number of respondents who agreed (including “somewhat agree” and “strongly agree”) to those who disagreed (including “somewhat disagree” and “strongly disagree”). For example, the ratio of respondents agreeing that they would recommend Go to respondents disagreeing was 19 to 1.

What do you like most about Go? 595 (17%) simplicity 543 (15%) easy 523 (15%) concurrency 495 (14%) simple 454 (13%) fast 293  (8%) syntax 287  (8%) standard library 286  (8%) tooling 270  (8%) static 266  (7%) performance 235  (7%) speed 202  (6%) interfaces 184  (5%) channels 183  (5%) community 180  (5%) good 177  (5%) compilation 177  (5%) goroutines 167  (5%) binary 156  (4%) great 148  (4%) tools 146  (4%) compiled 137  (4%) compile 127  (4%) type 124  (3%) small 118  (3%) c 114  (3%) gofmt 114  (3%) libraries 88  (2%) clean 87  (2%) easy to learn 82  (2%) deployment 78  (2%) memory 78  (2%) strong 76  (2%) concise 76  (2%) single binary 73  (2%) low 73  (2%) static typing 71  (2%) build 68  (2%) easy to read 63  (2%) fast compilation 56  (2%) simple syntax 55  (2%) type system 54  (2%) simple language 51  (1%) easy concurrency 47  (1%) static binaries 46  (1%) go fmt 45  (1%) fast compile 43  (1%) small language 41  (1%) error handling 39  (1%) concurrency model 39  (1%) go routines 38  (1%) easy to use 38  (1%) statically typed 36  (1%) cross platform 35  (1%) concurrency primitives 35  (1%) goroutines channels 33  (1%) easy to write 27  (1%) great standard library 23  (1%) ease of use 940 (26%) No response

Reading the data: This question asked for write-in responses. The bars above show the fraction of surveys mentioning common words or phrases. Only words or phrases that appeared in twenty or more surveys are listed, and meaningless common words or phrases like “the” or “to be” are omitted. The displayed results do overlap: for example, the 287 responses that mentioned “standard library” do include the 27 listed separately that mentioned “great standard library.” However, nearly or completely redundant shorter entries are omitted: there are not twenty or more surveys that listed “standard” without mentioning “standard library,” so there is no separate entry for “standard.”

What changes would improve Go most? 572 (16%) generics 451 (13%) management 330  (9%) dependency 314  (9%) package 266  (7%) dependency management 164  (5%) library 159  (4%) gui 134  (4%) package management 134  (4%) vendoring 128  (4%) debugger 126  (4%) libraries 122  (3%) standard 117  (3%) type 109  (3%) error 94  (3%) system 89  (2%) types 88  (2%) official 85  (2%) tools 84  (2%) c 82  (2%) gopath 78  (2%) performance 70  (2%) error handling 70  (2%) ide 69  (2%) package manager 66  (2%) documentation 66  (2%) faster 64  (2%) good 63  (2%) simple 63  (2%) tool 62  (2%) mobile 60  (2%) debugging 57  (2%) build 56  (2%) packages 55  (2%) easier 55  (2%) standard library 55  (2%) tooling 54  (2%) interface 51  (1%) dependencies 51  (1%) generic 48  (1%) programming 48  (1%) versioning 47  (1%) syntax 45  (1%) compile 45  (1%) solution 44  (1%) framework 43  (1%) examples 43  (1%) gc 43  (1%) type system 42  (1%) gui library 41  (1%) templates 40  (1%) android 40  (1%) community 40  (1%) function 40  (1%) native 40  (1%) ui 40  (1%) web 39  (1%) functions 21  (1%) cross platform 1,215 (34%) No response

What is the biggest challenge you personally face using Go today? 249 (6.9%) lack 206 (5.7%) management 146 (4.1%) libraries 129 (3.6%) generics 127 (3.5%) dependency management 84 (2.3%) work 78 (2.2%) package 76 (2.1%) hard 68 (1.9%) time 67 (1.9%) good 67 (1.9%) java 66 (1.8%) gui 61 (1.7%) web 60 (1.7%) c 60 (1.7%) debugging 59 (1.6%) vendoring 58 (1.6%) projects 56 (1.6%) lack of generics 56 (1.6%) library 51 (1.4%) type 51 (1.4%) write 50 (1.4%) finding 49 (1.4%) ide 49 (1.4%) packages 48 (1.3%) dependencies 46 (1.3%) package management 45 (1.3%) debugger 44 (1.2%) adoption 42 (1.2%) people 41 (1.1%) learning 41 (1.1%) team 40 (1.1%) convincing 40 (1.1%) tools 39 (1.1%) error handling 39 (1.1%) interfaces 39 (1.1%) other languages 39 (1.1%) writing 38 (1.1%) interface 38 (1.1%) others 37 (1.0%) python 35 (1.0%) find 35 (1.0%) gopath 35 (1.0%) programming 34 (0.9%) can't 34 (0.9%) standard 33 (0.9%) build 33 (0.9%) tooling 32 (0.9%) generic 31 (0.9%) boilerplate 30 (0.8%) applications 30 (0.8%) developers 30 (0.8%) having 30 (0.8%) types 30 (0.8%) working 26 (0.7%) at work 26 (0.7%) using go 22 (0.6%) no generics 20 (0.6%) not enough 1,581 (44.0%) No response

If it were not for the following reasons I would use Go more: (ordered choice, up to 3) 1,485 (24, 14, 4%) I work on an existing project written in another language 1,160 (16, 12, 4%) My project / team / TL prefers another language 841 (11, 8, 5%) Go isn’t an appropriate fit for what I’m working on (eg. iOS, JS) 596 (6, 6, 4%) Go lacks critical libraries 412 (6, 3, 2%) Go lacks critical features 319 (3, 3, 3%) Not enough education or support resources for Go 121 (1, 1, 1%) Go lacks critical performance 374 (4, 3, 3%) Other 1,042 (29%) No response

If you desire, please elaborate on your reasons above. 58 (1.6%) c 58 (1.6%) java 58 (1.6%) libraries 50 (1.4%) python 47 (1.3%) web 45 (1.3%) generics 45 (1.3%) work 40 (1.1%) projects 34 (0.9%) languages 33 (0.9%) hard 32 (0.9%) lack 32 (0.9%) team 31 (0.9%) library 31 (0.9%) people 29 (0.8%) gui 25 (0.7%) good 25 (0.7%) performance 24 (0.7%) mobile 24 (0.7%) written 23 (0.6%) programming 23 (0.6%) time 22 (0.6%) golang 20 (0.6%) company 20 (0.6%) existing 20 (0.6%) great 20 (0.6%) php 20 (0.6%) tools 3,033 (84.4%) No response

Development and deployment

When asked which operating systems they develop Go on, 63% of respondents say they use Linux, 44% use MacOS, and 19% use Windows, with multiple choices allowed and 49% of respondents developing on multiple systems. The 51% of responses choosing a single system split into 29% on Linux, 17% on MacOS, 5% on Windows, and 0.2% on other systems.

Go deployment is roughly evenly split between privately managed servers and hosted cloud servers.

I primarily develop Go on: (multiple choice) 2,263 (63%) Linux 1,592 (44%) MacOS 682 (19%) Windows 82  (2%) Other 434 (12%) No response

My preferred code editor: (ordered choice, up to 2) 1,359 (25, 13%) Vim 814 (14, 9%) VSCode 676 (10, 9%) Atom 687 (13, 6%) IntelliJ 655 (10, 8%) Sublime Text 305 (6, 2%) Emacs 137 (2, 2%) Visual Studio 153 (3, 2%) LiteIDE 99 (1, 2%) Eclipse 37 (1, 1%) Acme 238 (4, 3%) Other 425 (12%) No response

How satisfied are you with Go support in your preferred editor: (single choice) 69 (1.9%) Very Dissatisfied 52 (1.4%) Dissatisfied 164 (4.6%) Somewhat Dissatisfied 134 (3.7%) Neither Satisfied or Unsatisfied 609 (16.9%) Somewhat Satisfied 1,258 (35.0%) Satisfied 838 (23.3%) Very Satisfied 471 (13.1%) No response

What one addition would make the biggest improvement to Go editing in your preferred editor? 180 (5.0%) debugging 136 (3.8%) debugger 116 (3.2%) refactoring 79 (2.2%) integration 72 (2.0%) tools 68 (1.9%) completion 58 (1.6%) editor 46 (1.3%) debug 43 (1.2%) code completion 43 (1.2%) work 41 (1.1%) vim 40 (1.1%) autocomplete 40 (1.1%) vscode 37 (1.0%) package 37 (1.0%) plugin 36 (1.0%) definition 36 (1.0%) easier 36 (1.0%) good 36 (1.0%) ide 36 (1.0%) intellij 35 (1.0%) faster 35 (1.0%) function 34 (0.9%) atom 34 (0.9%) interface 33 (0.9%) vim-go 32 (0.9%) gopath 31 (0.9%) integrated 30 (0.8%) working 29 (0.8%) auto 28 (0.8%) refactoring support 27 (0.8%) delve 27 (0.8%) type 26 (0.7%) guru 26 (0.7%) syntax 25 (0.7%) error 25 (0.7%) method 25 (0.7%) packages 25 (0.7%) plugins 24 (0.7%) compile 24 (0.7%) jump 23 (0.6%) features 23 (0.6%) find 23 (0.6%) goimports 23 (0.6%) navigation 23 (0.6%) performance 23 (0.6%) refactoring tools 23 (0.6%) works 22 (0.6%) autocompletion 22 (0.6%) debugging support 22 (0.6%) errors 22 (0.6%) gofmt 22 (0.6%) run 21 (0.6%) highlighting 21 (0.6%) save 21 (0.6%) setup 21 (0.6%) visual 20 (0.6%) documentation 20 (0.6%) great 2,291 (63.7%) No response

My team deploys Go/non-Go programs to: (multiple choice) 1,489 (41%) Self/Company Owned Servers (Go) 1,714 (48%) (non-Go) 928 (26%) AWS EC2 1,122 (31%) 503 (14%) None 249  (7%) 412 (11%) Digital Ocean 360 (10%) 292  (8%) AWS Container 343 (10%) 221  (6%) Google Compute Engine 186  (5%) 188  (5%) Google App Engine 94  (3%) 161  (4%) Google Container Engine (GKE) 115  (3%) 121  (3%) Heroku 185  (5%) 114  (3%) Microsoft Azure 210  (6%) 104  (3%) Linode 100  (3%) 94  (3%) AWS Lambda 233  (6%) 301  (8%) Other 297  (8%) 639 (18%) No response 660 (18%)

Working Effectively

We asked how strongly people agreed or disagreed with various statements about Go. Users most agreed that Go’s performance meets their needs (57:1 ratio agree versus disagree), that they are able to quickly find answers to their questions (20:1), and that they are able to effectively use Go’s concurrency features (14:1). On the other hand, users least agreed that they are able to effectively debug uses of Go’s concurrency features (2.7:1).

Users mostly agreed that they were able to quickly find libraries they need (7.5:1). When asked what libraries are still missing, the most common request by far was a library for writing GUIs. Another popular topic was requests around data processing, analytics, and numerical and scientific computing.

Of the 30% of users who suggested ways to improve Go’s documentation, the most common suggestion by far was more examples.

The primary sources for Go news are the Go blog, Reddit’s /r/golang and Twitter; there may be some bias here since these are also how the survey was announced.

The primary sources for finding answers to Go questions are the Go web site, Stack Overflow, and reading source code directly.

To what extent do you agree or disagree with the following statements: (strongly disagree, disagree, somewhat disagree, neutral, somewhat agree, agree, strongly agree) 3,094 (1, 2, 5, 6, 27, 32, 12%) I have a good understanding of Go best practices. (9.6:1) 3,083 (0, 1, 3, 4, 17, 41, 20%) I am able to quickly find answers to my questions. (20:1) 3,053 (0, 0, 1, 2, 7, 32, 42%) Go's performance meets my needs. (57:1) 2,523 (1, 3, 5, 14, 15, 26, 8%) Go's support for language interoperability meets my needs. (6.0:1) 3,049 (1, 2, 6, 7, 24, 34, 11%) I am able to quickly find libraries that I need. (7.5:1) 3,083 (1, 2, 4, 5, 18, 37, 20%) Go language, library, and tool documentation meet my needs. (11:1)

What Go libraries do you need that aren't available today? 208 (5.8%) gui 144 (4.0%) library 121 (3.4%) libraries 63 (1.8%) native 60 (1.7%) ui 53 (1.5%) good 33 (0.9%) orm 33 (0.9%) standard 33 (0.9%) web 32 (0.9%) framework 32 (0.9%) gui library 31 (0.9%) mobile 28 (0.8%) android 28 (0.8%) database 28 (0.8%) desktop 28 (0.8%) libs 28 (0.8%) sql 26 (0.7%) cross platform 25 (0.7%) processing 25 (0.7%) xml 24 (0.7%) api 24 (0.7%) machine learning 24 (0.7%) official 24 (0.7%) windows 23 (0.6%) soap 22 (0.6%) toolkit 21 (0.6%) pdf 21 (0.6%) python 20 (0.6%) bindings 20 (0.6%) graphics 20 (0.6%) package 2,498 (69.5%) No response

What changes would most improve the Go documentation? 512 (14%) examples 300  (8%) more examples 134  (4%) documentation 69  (2%) example 62  (2%) docs 49  (1%) godoc 34  (1%) usage 32  (1%) functions 32  (1%) package 31  (1%) good 29  (1%) function 29  (1%) great 29  (1%) packages 29  (1%) search 28  (1%) cases 26  (1%) best practices 26  (1%) libraries 23  (1%) doc 23  (1%) more example 22  (1%) code examples 21  (1%) syntax 20  (1%) interface 2,532 (70%) No response

To what extent do you agree or disagree with the following statements: (strongly disagree, disagree, somewhat disagree, neutral, somewhat agree, agree, strongly agree) 3,002 (1, 2, 6, 7, 23, 34, 11%) I am able to effectively diagnose bugs in my Go programs. (7.2:1) 2,725 (1, 2, 6, 13, 22, 24, 7%) I am able to effectively diagnose performance issues in my Go programs. (5.8:1) 2,932 (1, 2, 3, 5, 17, 33, 22%) I am able to effectively use Go's concurrency features (goroutines, channels, select). (14:1) 2,801 (2, 5, 11, 14, 23, 18, 5%) I am able to effectively debug uses of Go's concurrency features (goroutines, channels, select). (2.7:1)

Rank the following in terms of where you get Go answers from: (ordered choice, up to 5) 2,226 (23, 18, 12, 7, 3%) Stack Overflow 2,101 (30, 15, 8, 4, 1%) golang.org 1,814 (13, 17, 12, 7, 2%) Reading source code (e.g., standard library, open-source packages) 1,200 (3, 8, 12, 7, 4%) GitHub 854 (3, 7, 7, 5, 3%) golang-nuts mailing list (groups.google.com/d/forum/golang-nuts) 682 (2, 3, 5, 5, 3%) Reddit (r/golang) 630 (3, 4, 5, 3, 2%) Coworkers 334 (2, 2, 2, 2, 2%) Gopher Slack (invite.slack.golangbridge.org) 214 (1, 1, 2, 1, 1%) Friends 161 (0, 0, 1, 1, 1%) Twitter 156 (1, 1, 1, 1, 0%) IRC 126 (0, 1, 1, 1, 1%) Go Forum (forum.golangbridge.org) 262 (2, 2, 1, 1, 1%) Other 643 (18%) No response

Rank the following in terms of where you get Go news from: (ordered choice, up to 5) 1,659 (17, 14, 9, 4, 2%) blog.Golang.org 1,153 (17, 8, 4, 2, 1%) Reddit (r/golang) 1,053 (14, 8, 4, 3, 1%) Twitter 903 (6, 8, 6, 3, 1%) Hacker News 777 (9, 6, 4, 2, 0%) Golangweekly.com 633 (2, 6, 5, 4, 1%) Community Blogs 430 (2, 3, 4, 2, 1%) GitHub 418 (3, 3, 3, 2, 1%) golang-nuts mailing list (groups.google.com/d/forum/golang-nuts) 394 (3, 3, 3, 1, 1%) Coworkers 212 (1, 1, 2, 1, 1%) Gopher Slack (invite.slack.golangbridge.org) 203 (1, 2, 1, 1, 1%) Golangnews.com 199 (1, 2, 1, 1, 1%) golang-announce (groups.google.com/d/forum/golang-announce) 176 (1, 1, 1, 1, 1%) Go Time podcast 65 (0, 0, 0, 1, 0%) Go Forum (forum.golangbridge.org) 42 (0, 0, 0, 0, 0%) Facebook 160 (1, 1, 1, 0, 0%) Other 747 (21%) No response

I have attended: (multiple choice) 1,315 (37%) None 879 (24%) A Go meetup 523 (15%) A Go themed conference (GopherCon, GothamGo, etc) 276  (8%) A Go remote meetup / online event 186  (5%) Go training 165  (5%) A technical conference for it's Go content 43  (1%) A GoBridge event 37  (1%) A Women Who Go event 65  (2%) Other 993 (28%) No response

The Go Project

55% of respondents expressed interest in contributing in some way to the Go community and projects. Unfortunately, relatively few agreed that they felt welcome to do so (3.3:1) and even fewer felt that the process was clear (1.3:1). In 2017, we intend to work on improving the contribution process and to continue to work to make all contributors feel welcome.

Respondents agree that they are confident in the leadership of the Go project (9:1), but they agree much less that the project leadership understands their needs (2.6:1), and they agree even less that they feel comfortable approaching project leadership with questions and feedback (2.2:1). In fact, these were the only questions in the survey for which more than half of respondents did not mark “somewhat agree”, “agree”, or “strongly agree” (many were neutral or did not answer).

We hope that the survey and this blog post convey to those of you who are aren’t comfortable reaching out that the Go project leadership is listening. Throughout 2017 we will be exploring new ways to engage with users to better understand their needs.

I contribute to open source projects written in Go: (single choice) 1,227 (34%) Infrequently 890 (25%) Never 345 (10%) Monthly 295  (8%) Weekly 234  (7%) As part of my daily routine 604 (17%) No response

I have contributed or am interested in contributing in the following ways to the Go community and Projects: (multiple choice) 892 (25%) Standard library 663 (18%) Tools (go guru, go vet, go doc, etc) 602 (17%) Tutorials 560 (16%) Documentation 557 (15%) Community support via Stack Overflow, Slack, mailing list, etc 472 (13%) Community involvement (workgroups, meetup attendance) 440 (12%) Being a technical mentor 374 (10%) Toolchain (compiler, linker, etc) 275  (8%) Go Project maintenance (issue triage) 246  (7%) Event planning (meetup, conference, etc) 236  (7%) Language translation 165  (5%) General UX & Design contributions 154  (4%) golang.org website (code, UX, IA, content, etc) 92  (3%) Other 1,621 (45%) No response

To what extent do you agree or disagree with the following statements: (strongly disagree, disagree, somewhat disagree, neutral, somewhat agree, agree, strongly agree) 2,091 (1, 3, 5, 19, 10, 14, 6%) I feel welcome to contribute to Go (compiler, standard library, documentation, website) (3.3:1) 2,168 (3, 7, 9, 16, 10, 11, 4%) The process of contributing to the Go project is clear to me (1.3:1) 1,900 (1, 2, 5, 22, 8, 11, 3%) The Go project leadership understands my needs (2.6:1) 2,114 (2, 4, 6, 18, 10, 14, 5%) I feel comfortable approaching the Go project leadership with questions and feedback (2.2:1) 2,374 (1, 1, 3, 12, 9, 24, 15%) I am confident in the leadership of Go (9.0:1)

What is the biggest challenge facing the Go project today? 71 (2.0%) community 68 (1.9%) google 63 (1.8%) generics 62 (1.7%) management 49 (1.4%) adoption 45 (1.3%) lack 43 (1.2%) features 43 (1.2%) people 40 (1.1%) dependency management 37 (1.0%) java 32 (0.9%) languages 31 (0.9%) keeping 29 (0.8%) c 27 (0.8%) developers 27 (0.8%) leadership 24 (0.7%) good 24 (0.7%) libraries 24 (0.7%) package 23 (0.6%) simple 21 (0.6%) core 21 (0.6%) feature 20 (0.6%) programming 20 (0.6%) team 2,771 (77.1%) No response

Community

At the end of the survey, we asked some demographic questions. The country distribution of responses roughly matches the country distribution of site visits to golang.org, but the responses under-represent some Asian countries. In particular, India, China, and Japan each accounted for about 5% of the site visits to golang.org in 2016 but only 3%, 2%, and 1% of survey responses.

An important part of a community is making everyone feel welcome, especially people from under-represented demographics. We asked an optional question about identification across a few diversity groups. 37% of respondents left the question blank and 12% of respondents chose “I prefer not to answer”, so we cannot make many broad conclusions from the data. However, one comparison stands out: the 9% who identified as underrepresented agreed with the statement “I feel welcome in the Go community” by a ratio of 7.5:1, compared with 15:1 in the survey as a whole. We aim to make the Go community even more welcoming. We support and are encouraged by the efforts of organizations like GoBridge and Women Who Go.

The final question on the survey was just for fun: what’s your favorite Go keyword? Perhaps unsurprisingly, the most popular response was go, followed by defer, func, interface, and select.

To what extent do you agree or disagree with the following statements: (strongly disagree, disagree, somewhat disagree, neutral, somewhat agree, agree, strongly agree) 2,701 (1, 1, 2, 11, 10, 31, 19%) I feel welcome in the Go community. (15:1)

What changes would make the Go community more welcoming? 115 (3.2%) community 52 (1.4%) people 32 (0.9%) r/golang 31 (0.9%) go community 30 (0.8%) google 30 (0.8%) reddit 24 (0.7%) welcoming 23 (0.6%) official 23 (0.6%) open 22 (0.6%) code of conduct 21 (0.6%) golang 21 (0.6%) team 3,017 (83.9%) No response

In which country do you currently reside? (single choice) 928 (26%) United States of America 253  (7%) Germany 168  (5%) United Kingdom 148  (4%) Russia 119  (3%) France 112  (3%) Canada 91  (3%) India 73  (2%) China 72  (2%) Australia 55  (2%) Netherlands 54  (2%) Spain 45  (1%) Sweden 43  (1%) Poland 40  (1%) Italy 36  (1%) Brazil 36  (1%) Switzerland 35  (1%) Ukraine 27  (1%) Japan 24  (1%) Czech Republic 23  (1%) Belgium 441 (12%) Other 772 (21%) No response

We want the Go community to be inclusive; we want to see how we're doing and how to improve. Please select the groups you identify with: (multiple choice) 1,499 (42%) I do not identify as part of an underrepresented group 438 (12%) I prefer not to answer 101  (3%) I identify as LGBTQIA 95  (3%) I identify as ethnically or racially underrepresented 77  (2%) I identify as neurodiverse or as having a disability 49  (1%) I identify as a woman 47  (1%) Write-in: objection to the question. 38  (1%) I identify as part of an underrepresented group, but I prefer not to specify 34  (1%) I identify with an underrepresented group not listed. 1,332 (37%) No response

Just for fun: What is your favorite Go keyword? 854 (24%) go 455 (13%) defer 253  (7%) func 240  (7%) select 227  (6%) interface 145  (4%) struct 139  (4%) chan 129  (4%) range 67  (2%) fallthrough 56  (2%) switch 53  (1%) for 48  (1%) type 47  (1%) map 44  (1%) goto 36  (1%) import 22  (1%) if 20  (1%) package 19  (1%) var 17  (0%) const 14  (0%) continue 13  (0%) return 12  (0%) break 3  (0%) else 2  (0%) case 2  (0%) default 678 (19%) No response

Is there anything else you would like to share with us? 95 (2.6%) thanks 94 (2.6%) great 86 (2.4%) thank you 47 (1.3%) keep up the good work 47 (1.3%) programming 43 (1.2%) community 39 (1.1%) c 37 (1.0%) awesome 33 (0.9%) i love 31 (0.9%) people 29 (0.8%) golang 27 (0.8%) great work 27 (0.8%) java 27 (0.8%) languages 26 (0.7%) fun 26 (0.7%) job 26 (0.7%) time 25 (0.7%) love go 24 (0.7%) generics 24 (0.7%) team 23 (0.6%) projects 22 (0.6%) best 22 (0.6%) wish 22 (0.6%) years 21 (0.6%) simple 2,886 (80.3%) No response

By Steve Francia, for the Go team

Go 1.8 is released

16 February 2017

Today the Go team is happy to announce the release of Go 1.8. You can get it from the download page. There are significant performance improvements and changes across the standard library.

The compiler back end introduced in Go 1.7 for 64-bit x86 is now used on all architectures, and those architectures should see significant performance improvements. For instance, the CPU time required by our benchmark programs was reduced by 20-30% on 32-bit ARM systems. There are also some modest performance improvements in this release for 64-bit x86 systems. The compiler and linker have been made faster. Compile times should be improved by about 15% over Go 1.7. There is still more work to be done in this area: expect faster compilation speeds in future releases.

Garbage collection pauses should be significantly shorter, usually under 100 microseconds and often as low as 10 microseconds.

The HTTP server adds support for HTTP/2 Push, allowing servers to preemptively send responses to a client. This is useful for minimizing network latency by eliminating roundtrips. The HTTP server also adds support for graceful shutdown, allowing servers to minimize downtime by shutting down only after serving all requests that are in flight.

Contexts (added to the standard library in Go 1.7) provide a cancelation and timeout mechanism. Go 1.8 adds support for contexts in more parts of the standard library, including the database/sql and net packages and Server.Shutdown in the net/http package.

It's now much simpler to sort slices using the newly added Slice function in the sort package. For example, to sort a slice of structs by their Name field:

sort.Slice(s, func(i, j int) bool { return s[i].Name < s[j].Name })

Go 1.8 includes many more additions, improvements, and fixes. Find the complete set of changes, and more information about the improvements listed above, in the Go 1.8 release notes.

To celebrate the release, Go User Groups around the world are holding release parties this week. Release parties have become a tradition in the Go community, so if you missed out this time, keep an eye out when 1.9 nears.

Thank you to over 200 contributors who helped with this release.

By Chris Broadfoot

See the index for more articles.