Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Gophers! Go, google's open source language - WXG Guildford 2013

146e52d49d361f85c0945487452fc6a0?s=47 Ben Lovell
October 25, 2013

Gophers! Go, google's open source language - WXG Guildford 2013

Go was conceived within Google to scratch their itch for a fully featured systems programming language with a super-fast compiler and runtime performance close to that of the C programming language.

We'll take a high level glance at how Go can help you write performant and maintainable servers and applications, how Go's language-level concurrency constructs "go-routines" and "channels" make traditional multithreading headaches a thing of the past and a brief look into Go's "batteries included" amazing standard library.

Go is built from the ground up for concurrency - a commonly misunderstood term and often used interchangeably with parallelism. We'll talk about this distinction and why it is increasingly significant in the age of multicore and multi-CPU systems and servers.

Of course, Go isn't perfect. I'll take you on a tour of some of Go's controversial design decisions and the reasoning behind them. Hopefully turning the typical and initial reaction - "huh?" into "ah!"

This talk was presented at WXG Guildford. http://wxg.co.uk

146e52d49d361f85c0945487452fc6a0?s=128

Ben Lovell

October 25, 2013
Tweet

Transcript

  1. gophers! Ben Lovell

  2. benlovell _j

  3. 113581334398839860922 (thanks, google)

  4. None
  5. None
  6. sometimes we don’t get along…

  7. None
  8. None
  9. what is go? … and why does it exist

  10. go will be the server language of the future -

    Tobias Lütke, Shopify founder
  11. go is fast

  12. go is object-oriented (but not as you know it)

  13. go is statically typed

  14. go is garbage collected

  15. go is concurrent

  16. optimised for developer happiness

  17. a brief history of go

  18. started in 2007 by three googlers…

  19. Rob Pike

  20. Ken Thompson

  21. Robert Griesemer

  22. open sourced in 2009 (over 300 contributors to date)

  23. 1.0 release March 2012

  24. what was left out is more important than what was

    put in - UNIX philosophy
  25. hello, world!

  26. package main ! import "fmt" ! func main() { fmt.Println("Hello,

    world!") }
  27. the type system

  28. package main ! import "fmt" ! type Person string !

    func (person Person) Greet() { fmt.Printf("Hello, %s!\n", person) } ! func main() { person := Person("Ben") person.Greet() } !
  29. package main ! import "fmt" ! type Person struct {

    Name string Age int } ! func (person Person) Greet() { fmt.Println(person.Name) } ! func main() { person := Person{"Ben", 33} person.Greet() } !
  30. no classes…

  31. …no type hierarchy

  32. favour composition over inheritance

  33. arranging code in packages

  34. % export GOPATH=/gocode/ ! /gocode /gocode/src

  35. package person ! import "fmt" ! type Person struct {

    Name string } ! func (person Person) Greet() string { return fmt.Sprintf("Hello, %s", person.Name) } ~/gocode/src/person/person.go
  36. ~/gocode/src/main.go ~/gocode/src % go run main.go package main ! import

    ( "fmt" "person" ) ! func main() { person := person.Person{"Ben"} greeting := person.Greet() fmt.Println(greeting) } !
  37. visibility?

  38. start your identifier with a lowercase letter to make it

    private
  39. function arguments are copied

  40. package main ! import ( "fmt" "strings" ) ! func

    Upcase(name string) { name = strings.ToUpper(name) } ! func main() { name := "ben" Upcase(name) ! fmt.Println(name) } ! // ben
  41. pointers! (scream)

  42. // BEN package main ! import ( "fmt" "strings" )

    ! func Upcase(name *string) { *name = strings.ToUpper(*name) } ! func main() { name := "ben" Upcase(&name) ! fmt.Println(name) } !
  43. the same applies to function receivers

  44. package main ! import "fmt" ! type Person struct {

    Name string } ! func (p Person) SetName(name string) { p.Name = name } ! func main() { p := Person{"Ben"} p.SetName("Jim") fmt.Println(p.Name) } ! // Ben
  45. // Jim package main ! import "fmt" ! type Person

    struct { Name string } ! func (p *Person) SetName(name string) { p.Name = name } ! func main() { p := Person{"Ben"} p.SetName("Jim") fmt.Println(p.Name) } !
  46. pointers are not just for reference semantics

  47. pointers are not just for reference semantics Christmas

  48. representing is-a with type embedding (well, kinda)

  49. // I’M BEN // I’m Ben type Person struct {

    Name string } ! func (p Person) Greet() { fmt.Println("I'm", p.Name) } ! type Manager struct { Person } ! func (m Manager) Greet() { fmt.Println("I'M", strings.ToUpper(m.Name)) } ! func main() { m := Manager{Person{"Ben"}} m.Greet() m.Person.Greet() }
  50. signature based polymorphism (quack quack)

  51. None
  52. interfaces

  53. type Person struct { Name string } ! func (p

    Person) Greet() { fmt.Println("I'm", p.Name) } ! type Manager struct { Person } ! func (m Manager) Greet() { fmt.Println("I'M", strings.ToUpper(m.Name)) } ! func greet(greeters ...Greeter) { for _, g := range greeters { g.Greet() } } ! type Greeter interface { Greet() } ! func main() { greet(Person{"Ben"}, Manager{Person{"Bob"}}, Person{"Anne"}) }
  54. interfaces are implicitly satisfied

  55. querying for support and casting

  56. func greet(greeters ...interface{}) { for _, g := range greeters

    { g.(Greeter).Greet() } }
  57. don’t. there are safe idioms

  58. func greet(greeters ...interface{}) { for _, g := range greeters

    { greetable, ok := g.(Greeter) if ok { greetable.Greet() } else { fmt.Println("Whoops!") } } } ! func main() { greet(Person{"Ben"}, "WHOA!", Person{"Anne"}) } ! // I’m Ben // Whoops! // I’m Anne
  59. error handling (the error interface!)

  60. type error interface { Error() string }

  61. // os.Open signature func Open(name string) (file *File, err error)

    ! ! f, err := os.Open("file.txt") if err != nil { log.Fatal(err) } // do something with the open file
  62. f, err := os.Open("file.txt") if err != nil { log.Fatal(err)

    } ! defer f.Close() // do something with the *File f
  63. concurrency (kind hard of is it)

  64. communicating sequential processes

  65. don’t communicate by sharing memory share memory by communicating

  66. three simple constructs

  67. go routines (lightweight threads)

  68. func main() { go greet() ! // hang around a

    while time.Sleep(2 * time.Second) } ! func greet() { fmt.Println("Hi!") }
  69. channels (for communication)

  70. //make a channel c := make(chan int) ! //send on

    the channel c <- 1 ! //receive from the channel val := <- c
  71. func ping(c chan string) { for i := 0; ;

    i++ { c <- "ping" } } ! func printer(c chan string) { for { msg := <- c fmt.Println(msg) time.Sleep(time.Second * 1) } } ! func main() { c := make(chan string) ! go ping(c) go printer(c) ! time.Sleep(time.Second * 10) }
  72. func main() { s := make(chan int) ! go greet(s)

    s <- 1 } ! func greet(signaller chan int) { <- signaller fmt.Println("Hi!") }
  73. func main() { functions := make(chan func(int, int)(int)) go executor(functions)

    ! functions <- add functions <- multiply functions <- subtract } ! func add(x, y int) int { return x + y } ! func multiply(x, y int) int { return x * y } ! func subtract(x, y int) int { return x - y } ! func executor(functions chan func(int, int)(int)) { for f := range functions { fmt.Println("The result is: ", f(10, 10)) } }
  74. func main() { functions := make(chan func(int, int)(int)) go executor(functions)

    ! functions <- add functions <- multiply functions <- subtract } ! func add(x, y int) int { return x + y } ! func multiply(x, y int) int { return x * y } ! func subtract(x, y int) int { return x - y } ! func executor(functions chan func(int, int)(int)) { for f := range functions { fmt.Println("The result is: ", f(10, 10)) } } The result is: 20 The result is: 100 The result is: 0
  75. select

  76. func printer(c chan string, d chan string) { for {

    select { case x := <- c: fmt.Println(x) case y := <- d: fmt.Println(y) case <- time.After(1 * time.Second): fmt.Println("Timeout!") } } } ! func main() { c := make(chan string) d := make(chan string) ! go ping(c) go ping(d) go printer(c, d) ! time.Sleep(time.Second * 10) }
  77. toolchain

  78. % go run

  79. % go fix

  80. % go run main.go —race

  81. % go fmt

  82. % go get

  83. % go doc

  84. % go test

  85. what I didn’t cover…

  86. thanks! @benlovell