The Go Programming Language


Sydney University

March 23, 2010

Go

New

Experimental

Concurrent

Garbage Collected

Systems Language

Hello, world

package main

import "fmt"

func main() {
	fmt.Printf("Hello, 世界\n")
}

Hello, world 2.0

Serving http://localhost:8080/world

package main

import (
	"fmt"
	"http"
)

func handler(c *http.Conn, r *http.Request) { 
	fmt.Fprintf(c, "Hello, %s.", r.URL.Path[1:]) 
}

func main() {
	http.ListenAndServe(":8080",
			http.HandlerFunc(handler))
}

New

It's about two years old:

Why invent a new language? Older languages weren't designed for concurrency, but modern software needs it:

New

Older languages are also frustrating on a day-to-day basis

Statically-typed languages (C, C++, Java) have issues:


Dynamic languages (Python, JavaScript) fix some issues but introduce others:

Go has the lighter feel of a scripting language but is compiled

New

Large C++ programs (e.g. Firefox, OpenOffice, Chromium) have enormous build times:

On a Mac (OS X 10.5.8, gcc 4.0.1):

In Go: import "fmt" reads one file: 184 lines summarizing 7 packages

New

Compilation demo

Experimental

Go is still unproven

Language is still evolving

Package library is incomplete

Concurrent garbage collection is an active research problem

Reviving forgotten concepts:

Concurrent

Unix philosophy: write programs that do one thing and do it well

Connect them with pipes:

Unlike other languages, Go makes it easy to:

Concurrent

Start a new flow of control with the go keyword

Parallel computation is easy:

func main() {
	go expensiveComputation(x, y, z)
	anotherExpensiveComputation(a, b, c)
}

Roughly speaking, a goroutine is like a thread, but lighter weight:

Concurrent

Consider web servers ("the C10k problem"):

	for {
		rw := socket.Accept()
		conn := newConn(rw, handler)
		go conn.serve()
	}

Concurrent

Let's look again at our simple parallel computation:

func main() {
	go expensiveComputation(x, y, z)
	anotherExpensiveComputation(a, b, c)
}

This story is incomplete:

Concurrent

Goroutines communicate with other goroutines via channels

func computeAndSend(ch chan int, x, y, z int) {
	ch <- expensiveComputation(x, y, z)
}

func main() {
	ch := make(chan int)
	go computeAndSend(ch, x, y, z)
	v2 := anotherExpensiveComputation(a, b, c)
	v1 := <-ch
	fmt.Println(v1, v2)
}

Concurrent

In traditional concurrent programs, you communicate by sharing memory. In Go, you share memory by communicating:

Threads and locks are concurrency primitives; CSP is a concurrency model:

Learning CSP changes the way you think about concurrent programming:

Garbage Collected

Automatic memory management makes writing (and maintaining) programs easier

Especially in a concurrent world:

Large C++ programs usually end up with semi-automatic memory management anyway, via "smart pointers"

Mixing the two models can be problematic:

Garbage Collected

Go is also a safer language:

No buffer overflow exploits

Systems Language

This just means you could write decently large programs in Go:

Systems Language

Garbage collection has a reputation for being "slower"

We're expecting Go to be slightly slower than optimized C, but faster than Java, depending on the task. Nonetheless:

Memory layout can drastically affect performance. These two designs are equivalent in Go, but significantly different in Java:

type Point struct { X, Y int }
type Rect struct { P0, P1 Point }

// or ...

type Rect struct { X0, Y0, X1, Y1 int }

Systems Language

Quote from http://loadcode.blogspot.com/2009/12/go-vs-java.html

"[Git] is known to be very fast. It is written in C. A Java version JGit was made. It was considerably slower. Handling of memory and lack of unsigned types was some of the important reasons.

Shawn O. Pearce wrote on the git mailinglist:

Like C, Go does allow unsigned types and defining data structures containing other data structures as continuous blocks of memory."

Go

New

Experimental

Concurrent

Garbage Collected

Systems Language

And more:

Questions?