The Go Programming Language
Sydney University
March 23, 2010
 
	Hello, world 2.0
	
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))
}
 
	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:
	
		- Goroutines have segmented stacks, and typically smaller stacks
 
		- This requires compiler support. Goroutines can't just be a C++ library on top of a thread library
 
	
 
	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:
	
		- How do we know when the two computations are done?
 
		- What are their values?
 
	
 
	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)
}
 
	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:
	
		- Fast and buggy is worse than almost-as-fast and correct
 
		- It is easier to optimize a correct program than to correct an optimized program
 
		- Fundamentally, it's simply a trade-off we're willing to make
 
	
	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 }