Go for Javaneros (Javaïstes?) #go4java Francesc Campoy Gopher and Developer Advocate Google @francesc campoy@golang.org * What is Go? Go is an open-source programming language - created at Google, - to solve Google-scale problems. .image go4java/img/gopher.jpg 450 _ * Who uses Go? Google: - YouTube - dl.google.com Others: - dotCloud (Docker) - SoundCloud - Canonical - CloudFlare - Mozilla - ... [[/wiki/GoUsers][go.dev/wiki/GoUsers]] * Who uses Go? .image go4java/img/trends.png _ 800 .caption Google Trends for [[http://www.google.com/trends/explore#q=golang][golang]] * Why Go? * Simplicity Minimal design .image go4java/img/perfection.jpg * Consistency Orthogonal features .image go4java/img/lego.jpg 400 _ .caption By Kenny Louie from Vancouver, Canada [[http://creativecommons.org/licenses/by/2.0][CC-BY-2.0]], via Wikimedia Commons * Readability “The ratio of time spent reading (code) versus writing is well over 10 to 1 ... (therefore) making it easy to read makes it easier to write.” ― Robert C. Martin .image go4java/img/piet.png 500 600 * Safety Type safety, no buffer overflows, no pointer arithmetic. .image go4java/img/baby.jpg 500 500 * Built-in concurrency features “In a concurrent world, imperative is the wrong default!” - Tim Sweeney Communicating Sequential Processes - Hoare (1978) .image go4java/img/conc.jpg _ 1000 * Speed .image go4java/img/fast.jpg 500 _ * Let's dive in * Go and Java common aspects Go and Java are - object oriented - garbage collected - statically typed - part of the C family * Object oriented flavors Go is Object Oriented, but doesn't have the keywords: - `class`, - `extends`, or - `implements`. * All types are created equal * Go types - primitive types int, uint, int8, uint8, ... bool, string float32, float64 complex64, complex128 - structs struct { Name string Age int } - slices and arrays []int, [3]string, []struct{ Name string } - maps map[string]int * Kinds of types (continued) - pointers *int, *Person - functions func(int, int) int - channels chan bool - interfaces interface { Start() Stop() } * Type declarations type [name] [specification] `Person` is a `struct` type. type Person struct { name string age int } `Celsius` is a `float64` type. type Celsius float64 * Function declarations func [name] ([params]) [return value] func [name] ([params]) ([return values]) A sum function: func sum(a int, b int) int { return a + b } A function with multiple returned values: func div(a, b int) (int, int) return a / b, a % b } Made clearer by naming the return values: func div(den, div int) (q, rem int) return a / b, a % b } * Method declarations func ([receiver]) [name] ([params]) ([return values]) A method on a struct: func (p Person) Major() bool { return p.age >= 18 } But also a method on a `float64`: func (c Celsius) Freezing() bool { return c <= 0 } _Constraint:_ Methods can be defined *only* on types declared in the same package. // This won't compile func (s string) Length() int { return len(s) } * Wait, pointers? Use `&` to obtain the address of a variable. a := "hello" p := &a Use `*` to dereference the pointer. fmt.Print(*p + ", world") No pointer arithmetic, no pointers to unsafe memory. a := "hello" p := &a p += 4 // no, you can't * Why pointers? Control what you pass to functions. - passing values, no side-effects: func double(x int) { x *= 2 } - passing pointers: side-effects possible: func double(x *int) { *x *= 2 } Control your memory layout. - compare []Person and []*Person * Method declarations on pointers Receivers behave like any other argument. Pointers allow modifying the pointed receiver: func (p *Person) IncAge() { p.age++ } The method receiver is a copy of a pointer (pointing to the same address). Method calls on nil receivers are perfectly valid (and useful!). func (p *Person) Name() string { if p == nil { return "anonymous" } return p.name } * Interfaces * Interfaces An interface is a set of methods. In Java: interface Switch { void open(); void close(); } In Go: type OpenCloser interface { Open() Close() } * It's all about satisfaction Java interfaces are satisfied *explicitly*. Go interfaces are satisfied *implicitly*. .image //upload.wikimedia.org/wikipedia/commons/thumb/2/29/Rolling_Stones_09.jpg/512px-Rolling_Stones_09.jpg _ 512 .caption Picture by Gorupdebesanez [[http://creativecommons.org/licenses/by-sa/3.0][CC-BY-SA-3.0]], via [[http://commons.wikimedia.org/wiki/File%3ARolling_Stones_09.jpg][Wikimedia Commons]] * Go: implicit satisfaction _If_a_type_defines_all_the_methods_of_an_interface,_the_type_satisfies_that_interface._ Benefits: - fewer dependencies - no type hierarchy - organic composition * Structural subtyping Think static duck typing, verified at compile time. .image go4java/img/duck.jpg 500 500 * FuncDraw: an example on interfaces .image go4java/img/funcdraw.png 500 700 * FuncDraw: package parser Package `parse` provides a parser of strings into functions. func Parse(text string) (*Func, error) { ... } `Func` is a struct type, with an `Eval` method. type Func struct { ... } func (p *Func) Eval(x float64) float64 { ... } * FuncDraw: package draw Package draw generates images given a function. func Draw(f *parser.Func) image.Image { for x := start; x < end; x += inc { y := f.Eval(x) ... } } `draw` depends on `parser` - makes testing hard Let's use an interface instead type Evaluable interface { Eval(float64) float64 } func Draw(f Evaluable) image.Image { ... } * Inheritance vs composition * Inheritance vs composition Lots of articles have been written about the topic. In general, composition is preferred to inheritance. Lets see why. * Runner .code go4java/BadInheritance.java /START_RUNNER/,/END_RUNNER/ * RunCounter is-a Runner that counts .code go4java/BadInheritance.java /START_COUNTING/,/END_COUNTING/ * Let's run and count What will this code print? .code go4java/BadInheritance.java /START_MAIN/,/END_MAIN/ Of course, this prints: running one running two running three my runner ran 6 tasks Wait! How many? * My runner ran 6 tasks? Six? Inheritance causes: - weak encapsulation, - tight coupling, - surprising bugs. .image go4java/img/badinheritance.png * Solution: use composition .code go4java/Composition.java /START_COUNTING/,/BREAK_COUNTING/ * Solution: use composition (continued) .code go4java/Composition.java /BREAK_COUNTING/,/END_COUNTING/ * Solution: use composition (continued) *Pros* - The bug is gone! - `Runner` is completely independent of `RunCounter`. - The creation of the `Runner` can be delayed until (and if) needed. *Cons* - We need to explicitly define the `Runner` methods on `RunCounter`: public String getName() { return runner.getName(); } - This can cause lots of repetition, and eventually bugs. * There's no inheritance in Go * There's no inheritance in Go Let's use composition directly: # .code go4java/runner/runner.go /type Task/,/END_TASK/ .code go4java/runner/runner.go /type Runner/,/END_RUNNER/ All very similar to the Java version. * RunCounter `RunCounter` has a `Runner` field. .code go4java/runner/runner.go /type RunCounter/, * Composition in Go Same pros and cons as the composition version in Java. We also have the boilerplate to proxy methods from `Runner`. .code go4java/runner/runner.go /runner.Name/ But we can remove it! * Struct embedding Expressed in Go as unnamed fields in a struct. It is still *composition*. The fields and methods of the embedded type are defined on the embedding type. Similar to inheritance, but the embedded type doesn't know it's embedded. * Example of struct embedding Given a type `Person`: .code go4java/embedsample.go /Person/,/Hi/ We can define a type `Employee` embedding `Person`: .code go4java/embedsample.go /Employee/,/}/ All fields and methods from `Person` are available on `Employee`: .code go4java/embedsample.go /var/,/Introduce/ * Struct embedding .code go4java/runner/embed.go /type RunCounter2/, * Is struct embedding like inheritance? No, it is better! It is composition. - You can't reach into another type and change the way it works. - Method dispatching is explicit. It is more general. - Struct embedding of interfaces. * Is struct embedding like inheritance? Struct embedding is selective. .code go4java/writecounter.go /WriteCounter/,/MAIN/ WriteCounter can be used with any `io.ReadWriter`. .play go4java/writecounter.go /func main/,/^}/ * Easy mocking What if we wanted to fake a part of a `net.Conn`? type Conn interface { Read(b []byte) (n int, err error) Write(b []byte) (n int, err error) Close() error LocalAddr() Addr RemoteAddr() Addr SetDeadline(t time.Time) error SetReadDeadline(t time.Time) error SetWriteDeadline(t time.Time) error } I want to test `handleCon`: .code go4java/loopback.go /handleCon/ - We could create a `fakeConn` and define all the methods of `Conn` on it. - But that's a lot of boring code. * Struct embedding of interfaces _WARNING_:_Cool_stuff_ If a type T has an embedded field of a type E, all the methods of E will be defined on T. Therefore, if E is an interface T satisfies E. * Struct embedding of interfaces (continued) We can test `handleCon` with the `loopBack` type. .code go4java/loopback.go /loopBack/,/^}/ Any calls to the methods of `net.Conn` will fail, since the field is nil. We redefine the operations we support: .code go4java/loopback.go /Read/, * Concurrency * Concurrency It is part of the language, not a library. Based on two concepts: - goroutines: lightweight threads - channels: typed pipes used to communicate and synchronize between goroutines So cheap you can use them whenever you want. .image go4java/img/funnelin.jpg 300 700 * Sleep and talk .code go4java/conc1.go /sleepAndTalk/,/^}/ We want a message per second. .play go4java/conc1.go /func main/,/^}/ What if we started all the `sleepAndTalk` concurrently? Just add `go`! * Concurrent sleep and talk .play go4java/conc2.go /func main/,/^}/ That was fast ... When the `main` goroutine ends, the program ends. * Concurrent sleep and talk with more sleeping .play go4java/conc3.go /func main/,/^}/ But synchronizing with `Sleep` is a bad idea. * Communicating through channels `sleepAndTalk` sends the string into the channel instead of printing it. .code go4java/chan.go /sleepAndTalk/,/^}/ We create the channel and pass it to `sleepAndTalk`, then wait for the values to be sent. .play go4java/chan.go /func main/,/^}/ * Let's count on the web We receive the next id from a channel. .code go4java/goodcounter.go /nextID/,/^}/ We need a goroutine sending ids into the channel. .play go4java/goodcounter.go /func main/,/^}/ [[http://localhost:8080/next]] * Let's fight! `select` allows us to chose among multiple channel operations. .play go4java/battle.go /battle/,/^}/ Go - [[http://localhost:8080/fight?usr=go]] Java - [[http://localhost:8080/fight?usr=java]] * Chain of gophers .image go4java/img/chain.jpg Ok, I'm just bragging here * Chain of gophers .play go4java/goroutines.go /func f/, * Concurrency is very powerful And there's lots to learn! - [[/talks/2012/concurrency.slide#1][Go Concurrency Patterns]], by Rob Pike - [[/talks/2013/advconc.slide#1][Advanced Concurrency Patterns]], by Sameer Ajmani - [[/talks/2012/waza.slide#1][Concurrency is not Parallelism]], by Rob Pike .image go4java/img/busy.jpg * In conclusion Go is simple, consistent, readable, and fun. All types are equal - methods on any type Implicit interfaces - Structural typing - Less dependencies - Code testable and reusable Use composition instead of inheritance - Struct embedding to remove boilerplate. - Struct embedding of interfaces to satisfy them fast. Concurrency is awesome, and you should check it out. * What to do next? Learn Go on your browser with [[/tour/][go.dev/tour]] Find more about Go on [[/][go.dev]] Join the community at [[https://groups.google.com/forum/#!forum/Golang-nuts][golang-nuts]] Link to the slides [[/talks/2014/go4java.slide]]