github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2015/go4cpp.slide (about)

     1  Go for C++ developers
     2  
     3  Francesc Campoy
     4  Developer, Advocate, and Gopher at Google
     5  @francesc
     6  campoy@golang.org
     7  
     8  #go4cpp
     9  
    10  * Go for C++ developers
    11  
    12  Agenda:
    13  
    14  - let's talk about Go
    15  
    16  - how do I do X in Go?
    17  
    18  - concurrency, because it's awesome
    19  
    20  - Q & A: but feel free to interrupt anytime
    21  
    22  - We might not go through all the slides
    23  
    24  * About me
    25  
    26  *2011*  Joined Google as a Software Engineer
    27  
    28  - writing mostly in C++ and Python
    29  - used to think _smart_code_ was better than boring code
    30  
    31  *2012* Joined the Go team as a Developer Programs Engineer
    32  
    33  *2014*to*today* Developer Advocate for the Google Cloud Platform
    34  
    35  * Let's talk about Go
    36  
    37  * Go is
    38  
    39  Go is
    40  
    41  - open source
    42  
    43  - statically typed
    44  
    45  - object oriented (if you ask me)
    46  
    47  - compiled
    48  
    49  - memory safe
    50  
    51  - type safe
    52  
    53  * Why Go?
    54  
    55  Go was created for:
    56  
    57  - scalability
    58  
    59  - concurrency
    60  
    61  - simplicity
    62  
    63  * Who uses Go?
    64  
    65  Google:
    66  
    67  - YouTube
    68  - dl.google.com
    69  
    70  Others:
    71  
    72  - Docker
    73  - SoundCloud
    74  - Canonical
    75  - CloudFlare
    76  - Mozilla
    77  - ...
    78  
    79  [[http://golang.org/wiki/GoUsers][golang.org/wiki/GoUsers]]
    80  
    81  * Who uses Go?
    82  
    83  .image go4cpp/trends.png _ 800
    84  
    85  .caption Google Trends for [[http://www.google.com/trends/explore#q=golang][golang]]
    86  
    87  * Some Go features
    88  
    89  * Go types
    90  
    91  - primitive types
    92  
    93  	int, uint, int8, uint8, ...
    94  	bool, string
    95  	float32, float64
    96  	complex64, complex128
    97  
    98  - structs
    99  
   100  	struct {
   101  		Name string
   102  		Age  int
   103  	}
   104  
   105  - slices and arrays
   106  
   107  	[]int, [3]string, []struct{ Name string }
   108  
   109  - maps
   110  
   111  	map[string]int
   112  
   113  * Kinds of types (continued)
   114  
   115  - pointers
   116  
   117  	*int, *Person
   118  
   119  - functions
   120  
   121  	func(int, int) int
   122  
   123  - channels
   124  
   125  	chan bool
   126  
   127  - interfaces
   128  
   129  	interface {
   130  		Start()
   131  		Stop()
   132  	}
   133  
   134  * Type declarations
   135  
   136  	type [name] [specification]
   137  
   138  `Person` is a `struct` type.
   139  
   140  	type Person struct {
   141  		name string
   142  		age  int
   143  	}
   144  
   145  `Celsius` is a `float64` type.
   146  
   147  	type Celsius float64
   148  
   149  * Function declarations
   150  
   151  	func [name] ([params]) [return value]
   152  	func [name] ([params]) ([return values])
   153  
   154  A sum function:
   155  
   156  	func sum(a int, b int) int {
   157  		return a + b
   158  	}
   159  
   160  A function with multiple return values:
   161  
   162  	func divMod(a, b int) (int, int) {
   163  		return a / b, a % b
   164  	}
   165  
   166  Made clearer by naming the return values:
   167  
   168  	func divMod(den, div int) (quo, rem int) {
   169  		return den / div, den % div
   170  	}
   171  
   172  * Method declarations
   173  
   174  	func ([receiver]) [name] ([params]) ([return values])
   175  
   176  A method on a struct:
   177  
   178  	func (p Person) IsMinor() bool {
   179  		return p.age < 18
   180  	}
   181  
   182  But also a method on a `float64`:
   183  
   184  	func (c Celsius) Freezing() bool {
   185  		return c <= 0
   186  	}
   187  
   188  _Constraint:_ Methods can be defined *only* on types declared in the same package.
   189  
   190  	// This won't compile
   191  	func (s string) Length() int { return len(s) }
   192  
   193  * Declaring variables
   194  
   195  Normal declaration:
   196  
   197      var text string = "hello"
   198  
   199  You can omit types:
   200  
   201      var text = "hello"
   202  
   203  And inside of functions:
   204  
   205      text := "hello"
   206  
   207  Other types
   208  
   209      a := 0                             // int
   210      b := true                          // boolean
   211      f := 1.0                           // float64
   212      p := Person{"Francesc", "Campoy"}  // Person
   213  
   214  * No implicit numeric conversion
   215  
   216  Given types:
   217  
   218      type Celsius float64
   219  
   220      type Fahrenheit float64
   221  
   222  And the variables:
   223  
   224      var freezing Fahrenheit = 32
   225      var boiling Celsius = 100
   226  
   227  This code won't compile:
   228  
   229      sauna := (freezing + boiling) / 2
   230  
   231  There's no implicit numeric conversion in Go.
   232  
   233  * Pointers and memory allocation
   234  
   235  * Pointers
   236  
   237  Go has pointers:
   238  
   239      var p *int
   240      p = new(int)
   241  
   242  But no pointer arithmetics:
   243  
   244      var p *int = &a[0]
   245      var q = p+2            // invalid
   246  
   247  There's `new` but there's no `delete`.
   248  
   249  Memory is garbaged collected after it's no longer accessible.
   250  
   251  * Memory allocation
   252  
   253  The compiler decides where to allocate based on escape analysis.
   254  
   255  Using `new` doesn't imply using the heap:
   256  
   257  `stack.go`:
   258  
   259      func get() int {
   260          n := new(int)
   261          return *n
   262      }
   263  
   264  And not all values in the heap are created with `new`:
   265  
   266  `heap.go`:
   267  
   268      func get() *int {
   269          n := 4
   270          return &n
   271      }
   272  
   273  * Choosing what allocation you want
   274  
   275  You can *not* decide where a value is allocated.
   276  
   277  But you can see what kind of allocation is used:
   278  
   279      $ go tool 6g -m stack.go
   280  
   281      stack.go:3: can inline get
   282      stack.go:4: get new(int) does not escape
   283  
   284  Compare to:
   285  
   286      $ go tool 6g -m heap.go
   287  
   288      heap.go:3: can inline get
   289      heap.go:4: moved to heap: n
   290      heap.go:5: &n escapes to heap
   291  
   292  * RAII
   293  
   294  _Resource_Acquisition_Is_Initialization_
   295  
   296  Provides:
   297  
   298  - encapsulation of acquisition and disposition of resources
   299  
   300  - exception safe
   301  
   302  An example:
   303  
   304      void write_to_file (const std::string & message) {
   305          // mutex to protect file access
   306          static std::mutex mutex;
   307       
   308          // lock mutex before accessing file
   309          // at the end of the scope unlock mutex
   310          std::lock_guard<std::mutex> lock(mutex);
   311  
   312          // mutual exclusion access section
   313          ...
   314      }
   315  
   316  * RAII in Go: defer
   317  
   318  The `defer` statement:
   319  
   320  - schedules a function call at the end of the current function
   321  
   322  - stacks all deferred calls - last in first out
   323  
   324      var m sync.Mutex
   325  
   326      func writeToFile(msg string) error {
   327          m.Lock()
   328          defer m.Unlock()
   329  
   330          // mutual exclusion access section
   331      }
   332  
   333  * Garbage collection
   334  
   335  Go is a garbage collected language
   336  
   337  But it's easy to limit heap allocations
   338  
   339  - many values are allocated on the stack
   340  
   341  - object pools: [[sync.Pool][http://golang.org/pkg/sync/#Pool]]
   342  
   343  - contiguous area of memory
   344  
   345  .play go4cpp/sizes.go /type/,
   346  
   347  * More about garbage collection
   348  
   349  Trusted in production.
   350  
   351  Brad Fitzpatrick's talk on migrating dl.google.com from C++ to Go:
   352  
   353  - [[https://talks.golang.org/2013/oscon-dl.slide#1][dl.google.com: Powered by Go]]
   354  
   355  Current state and road plan:
   356  
   357  - [[http://golang.org/s/go14gc][golang.org/s/go14gc]]
   358  
   359  * Inheritance vs Composition
   360  
   361  * Inheritance vs Composition
   362  
   363  - Inheritance breaks encapsulation
   364  
   365  - Composition causes boilerplate to proxy all methods
   366  
   367  Example:
   368  
   369      type Engine struct{}
   370  
   371      func (e Engine) Start() { ... }
   372      func (e Engine) Stop()  { ... }
   373  
   374  We want `Car` to be able to `Start` and `Stop` too.
   375  
   376  More detail in my talk [[http://talks.golang.org/2014/go4java.slide#32][Go for Javaneros]]
   377  
   378  * Struct embedding
   379  
   380  Composition + Proxy of selectors
   381  
   382  .play go4cpp/embedding.go /type/,
   383  
   384  * Struct embedding and the diamond problem
   385  
   386  What if two embedded fields have the same type?
   387  
   388  .play go4cpp/diamond.go /type/,
   389  
   390  * Struct embedding
   391  
   392  It looks like inheritance but _it_is_not_inheritance_.
   393  
   394  It is composition.
   395  
   396  Used to share implementations between different types.
   397  
   398  What if want to share behavior instead?
   399  
   400  * Interfaces
   401  
   402  * Interfaces
   403  
   404  An interface is a set of methods.
   405  
   406  In Java (C++ doesn't have interfaces)
   407  
   408      interface Switch {
   409          void open();
   410          void close();
   411      }
   412  
   413  In Go:
   414  
   415  	type OpenCloser interface {
   416  		Open()
   417  		Close()
   418  	}
   419  
   420  * It's all about satisfaction
   421  
   422  Java interfaces are satisfied *explicitly*.
   423  
   424  C++ abstract classes need to be extended *explicitly*
   425  
   426  Go interfaces are satisfied *implicitly*.
   427  
   428  .image //upload.wikimedia.org/wikipedia/commons/thumb/2/29/Rolling_Stones_09.jpg/512px-Rolling_Stones_09.jpg _ 512
   429  
   430  .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]]
   431  
   432  * Go: implicit satisfaction
   433  
   434  _If_a_type_defines_all_the_methods_of_an_interface,_the_type_satisfies_that_interface._
   435  
   436  Benefits:
   437  
   438  - fewer dependencies
   439  - no type hierarchy
   440  - organic composition
   441  
   442  * Structural subtyping
   443  
   444  Better than duck typing. Verified at compile time.
   445  
   446  .image go4cpp/duck.jpg 500 500
   447  
   448  * FuncDraw: an example on interfaces
   449  
   450  .image go4cpp/funcdraw.png 500 700
   451  
   452  * FuncDraw: package parser
   453  
   454  Package `parse` provides a parser of strings into functions.
   455  
   456  	func Parse(text string) (*Func, error) { ... }
   457  
   458  `Func` is a struct type, with an `Eval` method.
   459  
   460  	type Func struct { ... }
   461  
   462  	func (p *Func) Eval(x float64) float64 { ... }
   463  
   464  * FuncDraw: package draw
   465  
   466  Package draw generates images given a function.
   467  
   468  	func Draw(f *parser.Func) image.Image {
   469  		for x := start; x < end; x += inc {
   470  			y := f.Eval(x)
   471  			...
   472  		}
   473  	}
   474  
   475  `draw` depends on `parser`, which makes testing hard.
   476  
   477  * Breaking dependencies
   478  
   479  Let's use an interface instead
   480  
   481  	type Evaluable interface {
   482  		Eval(float64) float64
   483  	}
   484  
   485  	func Draw(f Evaluable) image.Image image.Image {
   486  		for x := start; x < end; x += inc {
   487  			y := f.Eval(x)
   488  			...
   489  		}
   490  	}
   491  
   492  * Advanced interfaces and composition
   493  
   494  * Struct embedding of interfaces
   495  
   496  Embedding an interface:
   497  
   498  - more types can be used
   499  - limits what is added to the embedding type
   500  
   501  Given:
   502  
   503      type Person struct {
   504          First string
   505          Last  string
   506          Age   int
   507      }
   508  
   509  `Employee` exposes the `Age` of `Person`
   510  
   511      type Employee struct {
   512          Person
   513      }
   514  
   515      e := Employee{Person{"John", "Doe", 49}}
   516  
   517  * Choosing what to proxy
   518  
   519  But we could hide it by choosing an interface:
   520  
   521      type Employee struct {
   522          Namer
   523      }
   524  
   525      type Namer interface {
   526          Name() string
   527      }
   528  
   529  And we need to make `Person` satisfy `Namer`
   530  
   531      func (e Person) Name() string { return e.First + e.Last }
   532  
   533  And the rest of the code still works:
   534  
   535      e := Employee{Person{"John", "Doe", 49}}
   536  
   537  * Easy mocking of interfaces
   538  
   539  Given this function:
   540  
   541  .code go4cpp/mock.go /func/,/^}/
   542  
   543  How would you test it?
   544  
   545  * Easy mocking of interfaces
   546  
   547  `net.Conn` is an interface defined in the `net` package of the standard library.
   548  
   549      type Conn interface {
   550          Read(b []byte) (n int, err error)
   551          Write(b []byte) (n int, err error)
   552          Close() error
   553          LocalAddr() Addr
   554          RemoteAddr() Addr
   555          SetDeadline(t time.Time) error
   556          SetReadDeadline(t time.Time) error
   557          SetWriteDeadline(t time.Time) error
   558      }
   559  
   560  We need a fake `net.Conn`!
   561  
   562  * One solution
   563  
   564  We could define a new type that satisfies `net.Conn`
   565  
   566      type fakeConn struct {}
   567  
   568      func (c fakeConn) Read(b []byte) (n int, err error) {...}
   569      func (c fakeConn) Write(b []byte) (n int, err error) {...}
   570      func (c fakeConn) Close() error {...}
   571      ...
   572  
   573  But, is there a better way?
   574  
   575  * The better way
   576  
   577  .code go4cpp/mock.go /type fakeConn/,/end_fake/
   578  
   579  And our test can look like:
   580  
   581  .play go4cpp/mock.go /func main/,
   582  
   583  * Concurrency
   584  
   585  * Concurrency
   586  
   587  It is part of the language, not a library.
   588  
   589  Based on three concepts:
   590  
   591  - goroutines: lightweight threads
   592  - channels: typed pipes used to communicate and synchronize between goroutines
   593  - select: control structure to coordinate concurrent operations
   594  
   595  .image go4cpp/funnelin.jpg 300 700
   596  
   597  * Sleep and talk
   598  
   599  .code go4cpp/conc1.go /sleepAndTalk/,/^}/
   600  
   601  We want a message per second.
   602  
   603  .play go4cpp/conc1.go /func main/,/^}/
   604  
   605  What if we started all the `sleepAndTalk` concurrently?
   606  
   607  Just add `go`!
   608  
   609  * Concurrent sleep and talk
   610  
   611  .play go4cpp/conc2.go /func main/,/^}/
   612  
   613  That was fast ...
   614  
   615  When the `main` goroutine ends, the program ends.
   616  
   617  * Concurrent sleep and talk with more sleeping
   618  
   619  .play go4cpp/conc3.go /func main/,/^}/
   620  
   621  But synchronizing with `Sleep` is a bad idea.
   622  
   623  * Communicating through channels
   624  
   625  `sleepAndTalk` sends the string into the channel instead of printing it.
   626  
   627  .code go4cpp/chan.go /sleepAndTalk/,/^}/
   628  
   629  We create the channel and pass it to `sleepAndTalk`, then wait for the values to be sent.
   630  
   631  .play go4cpp/chan.go /func main/,/^}/
   632  
   633  * Aside: a web server
   634  
   635  A production ready web server.
   636  
   637  .play go4cpp/webserver.go
   638  
   639  * Let's count on the web
   640  
   641  Why is this wrong?
   642  
   643  .play go4cpp/badcounter.go /nextID/,
   644  
   645  * Let's count on the web correctly
   646  
   647  We receive the next id from a channel.
   648  
   649  .code go4cpp/goodcounter.go /nextID/,/^}/
   650  
   651  We need to send ids into the channel.
   652  
   653  .code go4cpp/goodcounter.go /counter/,/^}/
   654  
   655  * Let's count on the web correctly
   656  
   657  And we need to do both at the same time.
   658  
   659  .play go4cpp/goodcounter.go /func main/,/^}/
   660  
   661  * Let's fight!
   662  
   663  `select` allows us to choose among multiple channel operations.
   664  
   665  .play go4cpp/battle.go /battle/,/^}/
   666  
   667  Go - [[http://localhost:8080/fight?usr=go]]
   668  C++ - [[http://localhost:8080/fight?usr=cpp]]
   669  
   670  * Chain of gophers
   671  
   672  .image go4cpp/chain.jpg
   673  
   674  Ok, I'm just bragging here
   675  
   676  * Chain of gophers
   677  
   678  .play go4cpp/goroutines.go /func f/,
   679  
   680  * Concurrency is very powerful
   681  
   682  And there's lots to learn!
   683  
   684  - [[http://talks.golang.org/2012/concurrency.slide#1][Go Concurrency Patterns]], by Rob Pike
   685  - [[http://talks.golang.org/2013/advconc.slide#1][Advanced Concurrency Patterns]], by Sameer Ajmani
   686  - [[http://talks.golang.org/2012/waza.slide#1][Concurrency is not Parellelism]], by Rob Pike
   687  
   688  .image go4cpp/busy.jpg
   689  
   690  * In conclusion
   691  
   692  - Go is simple, consistent, readable, and fun.
   693  
   694  - All types are equal: methods on any type.
   695  
   696  - Implicit satisfaction of interfaces makes code easier to reuse.
   697  
   698  - Use composition instead of inheritance.
   699  
   700  - Struct embedding is a powerful tool.
   701  
   702  - Concurrency is awesome, and you should check it out.
   703  
   704  * What to do next?
   705  
   706  Learn Go on your browser with [[http://tour.golang.org][tour.golang.org]]
   707  
   708  Find more about Go on [[http://golang.org][golang.org]]
   709  
   710  Join the community at [[https://groups.google.com/forum/#!forum/Golang-nuts][golang-nuts]]
   711  
   712  Link to the slides [[http://talks.golang.org/2015/go4cpp.slide]]