The State of Go

Where we are in May 2017

Francesc Campoy

Google Developer Advocate

Recording

A recording of this talk is available here.

2

Time flies

Go 1.7 is already 9 months old!

Go 1.8 was released on February 16th.

On May 1st we entered the release freeze for Go 1.9

Go 1.9 will be released early August.

3

Notes

The slides are available on talks.golang.org/2017/state-of-go-may.slide

Most of the code examples won't run except locally and using tip.

The playground runs Go 1.8.

4

Agenda

Changes since Go 1.8:

5

Changes to the language

6

Codebase Refactoring (with help from Go)

Article written by Russ Cox link

7

Gradual Code Repair

In reality, atomically changing all usages of an API is often impossible.

8

An example

Imagine we created a new package net/http/status.

First: create the new API

package status

const OK = http.StatusOK

Second: change each usage of http.StatusOK by status.OK.

if res.StatusCode != http.StatusOK {

if res.StatusCode != status.OK {

Third: remove the old API

9

Another example

Let's rename http.Get to http.DoGetPleaseAndThanks.

First: create the new API

func DoGetPleaseAndThanks(url string) (*http.Response, error) {
    return Get(url)
}

Second: change each usage of http.Get to http.DoGetPleaseAndThanks.

res, err := http.Get("https://golang.org")

res, err := http.DoGetPleaseAndThanks("https://golang.org")

Third: remove the old API

10

One last example

Let's move http.Client to http.Applicant.

First: create the new API

type Applicant Client
type Applicant struct { Client }
11

Alias declarations

An alias declaration is a new kind of type declaration.

type Applicant = http.Client

Both types are equivalent and completely interchangeable.

// +build go1.9

package main

import (
	"fmt"
	"net/http"
)

type Applicant = http.Client

func main() {
    fmt.Printf("%T", Applicant{})
}
12

Quaternions

issue #19813
13

The Standard library

14

A Twitter Poll

twitter poll
15

math/bits

Package bits implements bit counting and manipulation functions for the predeclared unsigned integer types.

Added to the standard library with proposal #18616.

// +build go1.9

package main

import (
	"fmt"
	"math/bits"
)

func main() {
	const n = 100
    fmt.Printf("%d (%b) has %d bits set to one\n", n, n, bits.OnesCount(n))

    fmt.Printf("%d reversed is %d\n", n, bits.Reverse(n))

    fmt.Printf("%d can be encoded in %d bits\n", n, bits.Len(n))
}
16

sync.Map

A new type has been added to the sync package with proposal #18177.

sync.Map is a concurrent map with amortized-constant-time loads, stores,and deletes.

17

sync.Map code sample

// +build go1.9

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
    var m sync.Map

    for i := 0; i < 3; i++ {
        go func(i int) {
            for j := 0; ; j++ {
                m.Store(i, j)
            }
        }(i)
    }

    for i := 0; i < 10; i++ {
        m.Range(func(key, value interface{}) bool {
            fmt.Printf("%d: %d\t", key, value)
            return true
        })
        fmt.Println()
        time.Sleep(time.Second)
    }
}
18

html/template panic on predefined escaper

What do you expect this code to print?

package main

import (
	"html/template"
	"log"
	"os"
)

type Foo struct{ Bar string }

func main() {
    tmpl, err := template.New("home").Parse(`
        <a title={{.Bar | html}}>
    `)
    if err != nil {
        log.Fatalf("could not parse: %v", err)
    }

    foo := Foo{"haha onclick=evil()"}
    if err := tmpl.Execute(os.Stdout, foo); err != nil {
        log.Fatalf("could not execute: %v", err)
    }
}

Predefined escapers in html template create a security concern.

Since 1.9 Execute will panic.

19

os.Exec

Let's imagine that we have a command getenv that prints an environment variable
using os.Getenv.

func main() {
    if len(os.Args) != 2 {
        fmt.Printf("use %s varname\n", os.Args[0])
        os.Exit(1)
    }
    fmt.Println(os.Getenv(os.Args[1]))
}

We can run it as follows:

$ foo=bar getenv foo
bar
20

os.Exec

What do you expect this code to print?

func main() {
    cmd := exec.Command("getenv", "foo")
    cmd.Env = append(os.Environ(), "foo=newbar")
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }
}

bar, or newbar?

21

another Twitter poll

Twitter poll
22

os.Exec

Cmd.Start now removes duplicates of environment variables, keeping the last one.

This code does what one expects:

cmd := exec.Command("prog")
cmd.Env = append(os.Environ(), "FOO=bar")
23

The Runtime

24

Benchmarks

note: values over 1.0 mean tip is faster
note: unofficial benchmark ran on my laptop while playing YouTube videos
25

More runtime

Garbage Collector

DWARF

26

The Tooling

27

go compiler: better errors!

Better error messaging for Allman style braces.

package main

func main()
{
    fmt.Println("that ain't gonna compile")
}

With go 1.8:

fail/main.go:4: syntax error: unexpected semicolon or newline before {

With go 1.9:

fail/main.go:3:6: missing function body for "main"
fail/main.go:4:1: syntax error: unexpected semicolon or newline before {
28

go compiler: more modular and faster

The compiler has been refactored into multiple packages.

cmd/go/internal/...

Issue #17639 made parsing concurrent.

The compiler is faster as a result.

29

go test

vendor directories are ignored by the go tool #19090:

go test ./...

You can now list all the tests to be executed, without running them #17209.

$ go test -test.list .
TestIntegration
TestEmbedStreams
TestEmbedFiles
30

godoc

You can now link to fields in a struct in the documentation #16753.

Note: This was actually introduced with Go 1.8!

31

... and much more!

32

The community

33

Go meetups

Gophers all around the world! go-meetups.appspot.com
34

Women Who Go

19 chapters already! www.womenwhogo.org
35

Women Who Go Gophercon Scholarship

WWG is sponsoring minority gophers from all over the world to attend Gophercon

36

Conferences:

37

Thank you

Francesc Campoy

Google Developer Advocate

Use the left and right arrow keys or click the left and right edges of the page to navigate between slides.
(Press 'H' or navigate to hide this message.)