Slide 1

Slide 1 text

THE STATE OF GO What's new since Go 1.12

Slide 2

Slide 2 text

bit.ly/sog-fosdem20 Maartje Eyskens @maartjeme Francesc Campoy @francesc

Slide 3

Slide 3 text

What's new since Go 1.12 ▪ Go 1.13 ▫ Released September 3rd 2019 ▪ Go 1.14 ▫ Expected February 2020 ▫ Beta 1 released 17 December 2019

Slide 4

Slide 4 text

Agenda Changes to: ● the language ● the standard library ● the tooling ● the community

Slide 5

Slide 5 text

CHANGES TO THE LANGUAGE

Slide 6

Slide 6 text

- New number literals (1.13) - Overlapping interfaces can be embedded (1.14) Changes to the language 6

Slide 7

Slide 7 text

● Added binary literals fmt.Println(0b101) // 5 ● Alternative syntax for octal literal fmt.Println(0o10, 0O10, 010) // 8 8 8 ● All number formats can now be imaginary fmt.Println(0b111i) // (0+7i) New number literals 7 Go 1.13

Slide 8

Slide 8 text

● Hexadecimal literals can now have: ○ floating point: ■ 1.2 = 1×160 + 2×16-1 = 1.125 ○ exponent ■ 1p3 = 1×160 × 23 = 8 ● Example: 0xa.cp3 | a.c = 10x160 + 12x16-1 = 10.75 | p3 = 23 = 8 | a.cp3 = 10.75 x 8 = 86 New number literals 8 Go 1.13

Slide 9

Slide 9 text

● Relatedly, shift counters can now be signed s := int64(2) fmt.Println(1 << s) // 8 ● But the following program will panic s := int64(-2) fmt.Println(1 << s) // panic: runtime error: negative shift amount New number literals 9 Go 1.13

Slide 10

Slide 10 text

● You can separate digits and/or their base with _ fmt.Println(1_000_000) // 1000000 fmt.Println(0b_1_0000) // 16 New number literals 10 Go 1.13

Slide 11

Slide 11 text

ParseInt support underscores only in “base guessing” mode. strconv.ParseInt("1_000", 0, 0) // 1000 strconv.ParseInt("0b1_000", 0, 0) // 8 strconv.ParseInt("0o1_000", 0, 0) // 512 strconv.ParseInt("0x1_000", 0, 0) // 4096 Otherwise, it will fail the same way it would fail with explicit base. strconv.ParseInt("0b1_000", 2, 0) // invalid syntax strconv.ParseInt("0b1000", 2, 0) // invalid syntax strconv.ParseInt("1000", 2, 0) // 8 A note on strconv.ParseInt 11 Go 1.13

Slide 12

Slide 12 text

Good ideas: - 1_000_000 / / a million - 2_02_2020 / / today! - 0x_FF_AA_EE / / #pink Bad ideas: - 0x15p1 / / 42 - ... Good ideas / bad ideas 12 Go 1.13

Slide 13

Slide 13 text

0x_A_A.d_bp8i

Slide 14

Slide 14 text

0x1p000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000001 A bug?

Slide 15

Slide 15 text

Try this at home! New printing verb %O and new behavior for %X. fmt.Printf("%x\n", 10) // a fmt.Printf("%x\n", 10.0) // 0x1.4p+03 fmt.Printf("%O\n", 10) // 0o12

Slide 16

Slide 16 text

- New number literals - Overlapping interfaces can be embedded Changes to the language 16

Slide 17

Slide 17 text

Before Go 1.14, this code would fail. type ReadWriteCloser interface { io.ReadCloser io.WriteCloser } If the repeated methods have same signature, it’s valid code. Before Go 1.14, this code would fail. type ReadWriteCloser interface { io.ReadCloser io.WriteCloser // duplicate method Close } If the repeated methods have same signature, it’s valid code. Overlapping interfaces 17 Go 1.14

Slide 18

Slide 18 text

Overlapping interfaces 18 Go 1.14 type MyCloser interface { Close() } type MyReadCloser interface { io.ReadCloser MyCloser // duplicate method Close } This code is still incorrect, since the method types differ.

Slide 19

Slide 19 text

Standard Library

Slide 20

Slide 20 text

● Removal of SSLv3 Breaking Changes 20 Go 1.14

Slide 21

Slide 21 text

● runtime.Goexit can no longer be aborted by a recursive panic/recover func maybeGoexit() { defer func() { fmt.Println(recover()) }() defer panic("cancelled Goexit!") runtime.Goexit() } func main() { maybeGoexit() fmt.Println("Hello, FOSDEM!") } Breaking Changes 21 Go 1.14 ~ $ go run . Cancelled Goexit! Hello FOSDEM!

Slide 22

Slide 22 text

● End of SSLv3 ● CA path for Alpine 3.7+ added ○ /etc/ssl/cert.pem ○ Not an issue as Alpine also links /etc/ssl/certs/ca-certificates.crt ○ Still need apk add ca-certificates What’s up with TLS 22

Slide 23

Slide 23 text

● Public keys: only 32 bytes ● Faster than RSA ● Publicly documented curve ● Not supported by any browsers (yet) Ed25519 23 Go 1.13

Slide 24

Slide 24 text

Improved handling of: - Error wrapping - Checking error values - Checking error types Error handling 24 Go 1.13

Slide 25

Slide 25 text

func main() { err := readConfig() if err == os.ErrNotExist { } } Issues: ● No good ability to pass additional context ● Hacky advanced checks Error handling: the problem 25 Go 1.13

Slide 26

Slide 26 text

Wrapping errors %w in fmt.Errorf() func readConfig() error { f, err := os.Open("config.json") if err != nil { return fmt.Errorf("Cannot open config.json: %w", err) } } Error handling: the solution 26 Go 1.13

Slide 27

Slide 27 text

Error Wrapping Before: return fmt.Errorf("Call failed: %v", err) fmt.Printf("%T", err) // *err.stringError Now: return fmt.Errorf("Call failed: %w", err) fmt.Printf("%T", err) // *err.wrapError Error handling: the solution 27 Go 1.13

Slide 28

Slide 28 text

Comparing wrapped errors err := readConfig() if errors.Is(err, os.ErrNotExist) { // file does not exist } Error handling 28 Go 1.13

Slide 29

Slide 29 text

Error type checking err := readDatabase() var e *QueryError if errors.As(err, &e) { // err is type QueryError // also works with wrap! } Error handling 29 Go 1.13

Slide 30

Slide 30 text

os.UserConfigDir() (string, error) $XDG_CONFIG_HOME, $HOME/.config on Linux $HOME/Library/Application Support on Darwin %AppData% on Windows Similar function added last year: os.UserHomeDir() (string, error) // 1.12 os 30 Go 1.13

Slide 31

Slide 31 text

● New package in Go 1.14. ● Fast hash functions on by sequences. ● Perfect for hash tables and similar. hash/maphash 31 Go 1.14

Slide 32

Slide 32 text

It is the fastest hashing function in the Go standard library. # go test -bench=. BenchmarkCRC64-2 55501 21247 ns/op BenchmarkCRC32-2 55454 20055 ns/op BenchmarkFNV-2 99736 10743 ns/op BenchmarkFNVa-2 108721 10475 ns/op BenchmarkAdler32-2 313054 4004 ns/op BenchmarkMaphash-2 475030 2477 ns/op Is it the fastest hashing function available in Go? hash/maphash 32 Go 1.14

Slide 33

Slide 33 text

Let’s compare to xxHash. # go test -bench=. BenchmarkCRC64-2 55501 21247 ns/op BenchmarkCRC32-2 55454 20055 ns/op BenchmarkFNV-2 99736 10743 ns/op BenchmarkFNVa-2 108721 10475 ns/op BenchmarkAdler32-2 313054 4004 ns/op BenchmarkMaphash-2 475030 2477 ns/op BenchmarkXXHash-2 1470511 747 ns/op github.com/cespare/xxhash hash/maphash 33 Go 1.14

Slide 34

Slide 34 text

The implementation exposes the existing code in the runtime. //go:noescape //go:linkname runtime_memhash runtime.memhash func runtime_memhash(p unsafe.Pointer, seed, s uintptr) uintptr hash/maphash 34 Go 1.14

Slide 35

Slide 35 text

Compare to how it was being used from dgraph-io/ristretto: //go:noescape //go:linkname memhash runtime.memhash func memhash(p unsafe.Pointer, h, s uintptr) uintptr type stringStruct struct { str unsafe.Pointer len int } func MemHash(data []byte) uint64 { ss := (*stringStruct)(unsafe.Pointer(&data)) return uint64(memhash(ss.str, 0, uintptr(ss.len))) } hash/maphash 35 Go 1.14

Slide 36

Slide 36 text

Let’s compare to xxHash. # go test -bench=. BenchmarkCRC64-2 55501 21247 ns/op BenchmarkCRC32-2 55454 20055 ns/op BenchmarkFNV-2 99736 10743 ns/op BenchmarkFNVa-2 108721 10475 ns/op BenchmarkAdler32-2 313054 4004 ns/op BenchmarkMaphash-2 475030 2477 ns/op BenchmarkXXHash-2 1470511 747 ns/op BenchmarkMemhash-2 4106250 293 ns/op github.com/dgraph-io/dgraph hash/maphash 36 Go 1.14

Slide 37

Slide 37 text

● 1.13: reflect .IsZero() ● 1.14: {T,B,TB}.Cleanup Testing 37

Slide 38

Slide 38 text

reflect.ValueOf(0).IsZero() // true reflect.ValueOf("").IsZero() // true reflect.ValueOf(struct{}{}).IsZero() // true reflect.ValueOf([]string{}).IsZero() // false reflect.ValueOf([]string(nil)).IsZero() // true Testing: reflect IsZero 38 Go 1.13

Slide 39

Slide 39 text

The testing package now supports cleanup functions on T, B, and TB. func Test_something(t *testing.T) { t.CleanUp(func() { fmt.Println("Clean up!") }) t.Run(tt.name,[...]) } This is useful with parallel tests and subtests Testing: Cleanup 39 Go 1.14

Slide 40

Slide 40 text

● 2 new methods on Duration: Microseconds and Milliseconds time.Second.Milliseconds() // 1_000 time.Second.Microseconds() // 1_000_000 Time 40 Go 1.13

Slide 41

Slide 41 text

Implementation: func (d Duration) Microseconds() int64 { return int64(d) / 0X1.F4P+09 } func (d Duration) Milliseconds() int64 { return int64(d) / 0X1.E848P+19 } Time 41 Go 1.13

Slide 42

Slide 42 text

TOOLING

Slide 43

Slide 43 text

Impossible not to talk about them, but too much to say. - GO111MODULE=auto doesn’t check GOPATH - GOSUMDB (sum.golang.org) - enables first time verification of modules - GOPRIVATE: manage GONOPROXY/GONOSUMDB - GOINSECURE: #YOLO. Go Modules 43

Slide 44

Slide 44 text

- You can set GO111MODULE to on, off, or auto (default) - Modules are enabled in auto when the current directory, or one of its parents, contains a go.mod file. - The read-only GOMOD variable indicates in which mode you are. - Output of go env GOMOD: Go Modules: enabling 44 go.mod not found go.mod found GO111MODULE=off GO111MODULE=on /dev/null /path/to/go.mod GO111MODULE=auto /path/to/go.mod

Slide 45

Slide 45 text

Go modules on Subversion Go 1.13 -

Slide 46

Slide 46 text

godoc -http is no more Go 1.13

Slide 47

Slide 47 text

go build -trimpath Go 1.13 ~ $ go build . && ./hello panic: Hello FOSDEM goroutine 1 [running]: main.main() /home/user/go/src/github.com/meyskens/state-of-go/panic.go:4 +0x39 ~ $ go build -trimpath . && ./hello panic: Hello FOSDEM goroutine 1 [running]: main.main() command-line-arguments/panic.go:4 +0x39

Slide 48

Slide 48 text

48 ● Trims your your specific CI setup ● Making reproducible builds! Why go build -trimpath? Go 1.13

Slide 49

Slide 49 text

RUNTIME

Slide 50

Slide 50 text

Better errors for out of range Given this buggy code: a := []int{1, 2, 3} fmt.Println(a[3]) In 1.12 and before: panic: runtime error: index out of range Since 1.13: panic: runtime error: index out of range [3] with length 3 Go 1.14

Slide 51

Slide 51 text

Defer got much faster for many cases! - basically as fast as a normal function call benchmark 1.12 ns/op 1.14 ns/op delta BenchmarkDefer-32 67.6 7.31 -89.19% BenchmarkDefer10-32 57.5 59.3 +3.13% BenchmarkDeferMany-32 157 168 +7.01% change: cmd/compile, cmd/link, runtime: make defers low-cost through inline code and extra funcdata Performance: defer Go 1.14

Slide 52

Slide 52 text

JSON encoding/decoding is faster! - 9% faster encoding - 38% faster decoding benchmark 1.12 MB/s 1.14 MB/s speedup BenchmarkCodeEncoder-32 2139.27 2332.60 1.09x BenchmarkCodeMarshal-32 2178.14 2113.87 0.97x BenchmarkCodeDecoder-32 364.06 503.32 1.38x BenchmarkUnicodeDecoder-32 30.25 37.16 1.23x BenchmarkCodeUnmarshal-32 351.67 353.34 1.00x change: encoding/json: speed up tokenization of literals Performance: JSON Go 1.14

Slide 53

Slide 53 text

Many improvements! - fewer bound checks - time.Timer is more performant - scheduling more efficient for high contention mutexes - and much more ... Performance: more Go 1.14

Slide 54

Slide 54 text

PORTS ▪ Go 1.13 Android 10 ▪ Go 1.13 requires macOS 10.11 or later ▪ Go 1.14 last to support darwin/arm(32) ▪ Go 1.14 added freebsd/arm64 ▪ Go 1.14 might support Dragonfly, Illumos, Solaris ▪ Go 1.14 dropped NaCl

Slide 55

Slide 55 text

Congratulations to tinygo on becoming a Google sponsored project! Tinygo, not so tiny budget!

Slide 56

Slide 56 text

▪ Added in Windows binaries ▫ Feature since Windows XP ▫ Marks memory as (non-)executable ▫ Enforced in the CPU Data Execution Prevention Go 1.14

Slide 57

Slide 57 text

CTRL_CLOSE_EVENT CTRL_LOGOFF_EVENT CTRL_SHUTDOWN_EVENT Windows Events Go 1.14 syscall.SIGTERM Windows Events Unix Syscalls

Slide 58

Slide 58 text

COMMUNITY

Slide 59

Slide 59 text

WOMEN WHO GO & GOBRIDGE MEETUPS 59 7 more than 2019: 37 chapters now!

Slide 60

Slide 60 text

Go Developer Network - 10k+ members - 172 meetups - 4.6k+ events - 137k+ RSVPs

Slide 61

Slide 61 text

conferences ▪ Go Devroom @ FOSDEM 2020 (you are here) ▪ Gophercon Israel, Tel Aviv February 3 ▪ CaptialGo, Washington DC March 27 ▪ Gophercon India, Goa March 28-29 ▪ Gophercon Russia, Moscow March 28 ▪ dotGo, Paris March 30 ▪ Gophercon Europe, Berlin April 23-26

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

Slides bit.ly/sog-fosdem20

Slide 64

Slide 64 text

Back in 2014

Slide 65

Slide 65 text

Back in 2014 @enneff @bradfitz

Slide 66

Slide 66 text

2015 ...

Slide 67

Slide 67 text

2016 ...

Slide 68

Slide 68 text

2017 …

Slide 69

Slide 69 text

2018 ...

Slide 70

Slide 70 text

Last year ... Last year

Slide 71

Slide 71 text

And this year!! (Sunday morning is hard)

Slide 72

Slide 72 text

Today

Slide 73

Slide 73 text

SCHEDULE

Slide 74

Slide 74 text

SCHEDULE

Slide 75

Slide 75 text

Lightning Talks: bit.ly/golight2020 ▪ 16:00 till 17:00 in UB2.525a (here) ▪ 8 minutes ▪ CfP deadline: Today 14:30 (Brussels time, duh) ▪ Submit at: bit.ly/golight2020

Slide 76

Slide 76 text

THANKS! Francesc and Maartje 76 Gophers by Renee French, Ashley McNamara, Egon Elbre, Sam Croswell and Miguel Molina, Marcus Olsson Glenda by Renee French