Go for C developers

Go for C developers

The talk about transitioning from C to Golang I gave at devfest Pisa 0.1

The pdf version is slightly messed up. Original version can be found at https://talks.godoc.org/github.com/fedepaol/go-for-c-devs-talk/goforcdevs.slide#1

9e13b6114dfd38952b3699dd779c6958?s=128

Federico Paolinelli

March 10, 2018
Tweet

Transcript

  1. Golang for C developers Federico Paolinelli List

  2. About me Lead developer at List C on daily basis

    Things I tinker with in my spare time: Android Python
  3. Let's talk about C

  4. Very simple You have Structs struct Book { char title[50];

    char author[50]; }; Book b; // a mess memset(&b, 0, sizeof(Book)); strcpy(b.title, "Golang"); and functions void printBook(struct Book book) { printf("Title: %s", book.title); printf("Author: %s", book.author); }
  5. Oh, and you have pointers int i = 5; void

    changeValue(int* i) { *i = 12; } int array[3] = {0, 1, 2}; printf("%d", *(array + 2 * sizeof(int)); // 2 Direct access to memory locations. It's only way to pass references around instead of copies.
  6. What I like about C fast direct control of things

    (pointers!) no hidden costs you understand what you are reading
  7. What I don't like about C verbose easy to shoot

    on your foot limited standard library dependency management
  8. The recipe for Go

  9. The recipe for Go Go back to the 70s /

    80s and nd a bunch of great programmers. Say, Ken Thompson, Rob Pike, people like that. Marinate them in Bell Labs for 30 years, during which time they code in C, keep developing Unix, invent Plan 9, UTF-8, and other wonderful things. Take them out, seduce them with Python, wow them with Google-scale computing. Add more amazing programmers (Brad Fitzpatrick for example), stir in Google’s near- unlimited resources. Ask them how they would do C now, if they could start from scratch. credits by Graham King (https://www.darkcoding.net/software/go-lang-after-four-months/)
  10. Can a language be fast and fun to use?

  11. Go's elevator pitch: fast (C-ish fast) good at networking and

    multiprocessing scales well easy to learn comprehensible
  12. Let's dive in

  13. Basic data types As in C, we do have integers,

    oats, booleans: var n int64 = 23 var n1 int = 28 var p float64 = 9.75 var r bool = true Go provides a higher level string type: var s string = "Hello" s = s + " Devfest" // s = "Hello devfest" s = s[1:5] // ello
  14. Arrays in C: int numbers[10]; for (int i = 0;

    i < 10; i++) numbers[i] = 0; length is not a property shortcut for pointer arithmetic (non initialized, out of bound errors write in memory) Arrays in Go: var a[3]int = [3]int{1,2,3} var b[3]int = [...]int{1,2,3} a[2] // 3 len(a) // 3 Fixed lenght Passed by value
  15. Slices var a s[]int = []int{1,2,3} s1 := a[1:3] //

    2, 3 s2 := make([]int, 3) // {0, 0, 0} var s3 s := append(s, 4) / s := append(s, s1...) // 1,2,3,4,2,3 Dynamically sized Automatically resized by append
  16. Maps var values = make(map[string]int) values["pr"] = 23 values["bdu"] =

    28 delete(m, "bdu") if age, ok := values["pr"]; !ok { /* ... */ } // if not found, age = 0 value no native equivalent in C
  17. Functions func f(a, b int) (string, error) { /* ...

    */ } multiple return values (error handling) rst class values can be anonymous func getAdder(toSum int) func(int) int { return func(arg int) int { return arg + toSum; } }
  18. Memory management

  19. Memory management in C heap vs stack int* bird =

    malloc(sizeof(int)) // lives in the heap, need to be freed int* f() { int b = 5; return &b; // BAD! } e cient the dev is in control of what lives in the stack and what in the heap easy to forget the lifecycle of malloc'ed objects
  20. Memory management in C

  21. Memory management in Go There are pointers too, which is

    good: the dev is in control of what is passed by value and what by reference func f() int* { int result = 28 return &result //result stored in the heap } garbage collected pointers are references to live objects: there is no way to mess up with the memory
  22. But I really really miss pointer arithmetic!

  23. Unsafe package The package name is self explanatory. It provides

    Pointers. A pointer value of any type can be converted to a Pointer. A Pointer can be converted to a pointer value of any type. func Float64bits(f float64) uint64 { return *(*uint64)(unsafe.Pointer(&f)) } Pointer arithmetic f := unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f))
  24. Nice things about GO

  25. It's safer Prevents side e ects related to distractions assignement

    between di erent types requires explicit conversion int n = 1400.5 / 'c'; // ????? variables are initialized with zero values MyStruct* s = (MyStruct*) malloc(sizeof(MyStruct)); memset(s, 0, sizeof(MyStruct)); no pointer arithmetic MyStruct s; int* i = (&s + 3 * sizeof(int)); // ????
  26. Doing more with (a bit) less No ; nor ()

    around ifs Type inference, short variable declaration var s = "devfest" s1 := "devfest" // only inside a function Multiple return values (also, named return values) func f(arg int) (res int, err error) { /* ... */ }
  27. Doing more with less Range loops (in maps, slices and

    strings) for index , _ := range(mySlice) { /* ... */ } defer() to call nalizing operations inside a function no break in switch, switch cases can be conditions
  28. Productivity boost! Compiling is really fast

  29. Let's talk about OOP

  30. User de ned data structures C structs: struct Book {

    char title[50]; char author[50]; }; Book b; // a mess memset(&b, 0, sizeof(Book)); strcpy(b.title, "Golang"); Go Structs type book struct { title string author string } var b book // zero value var b1 book{title:"Golang"} // literal initializer
  31. Methods Just a special kind of functions (they have a

    receiver) Explicitly associated to objects or pointers type Dog struct { Animal } func (d Dog) bark() { // bark } func (d *Dog) feed() { d.weight++ }
  32. Interfaces Abstract types de ning a behaviour Satis ed implicitly

    type Driveable interface { func Drive() int } func (c Car) Drive (km int) {/* */} func (b Bike) Drive (km int) {/* */} var c Car{wheels : 4} var d Driveable = c Can be checked c, ok := d.(Car) // true c, ok := d.(Bike) // false switch d.(type) { case Car: // }
  33. Encapsulation

  34. Encapsulation in C static modi er for functions and variables

    Local to a .c le Directly related to exported names available during linking
  35. Encapsulation in Go: The visibility is related to the package

    Multiple les can belong to the same package The visibility is toggled by uppercasing / lowercasing Every le belongs to a package package mypackage var Exported int var notExported string
  36. The worst nightmare of every (C) programmer

  37. Knock knock. Race condition. Who's there?

  38. pthread.h Provide primitives to create and synchronize threads together. Mutexes

    Condition variables Semaphores Multithreading is today's goto : - hard to read / understand - di cult to debug What we need is a better solution for concurrency, easier to understand and to handle
  39. Enters goroutine Goroutines are lightweight threads managed by the Go

    runtime. go myFunction() Why lighter? smaller (altough variable) stack many goroutines can be share a single os thread scheduling not invoked periodically but as a consequence of synchronization It is practical to create hundreds of thousands of goroutines in the same address space
  40. Why are they di erent?

  41. Channels A channel is a communication mechanism between two goroutines

    ch := make(chan int) We can send values to a channel ch <- 23 or receive from a channel res := <- ch or just check if send has happened <- ch Channels can be bu ered or unbu ered. Sending on a full channel blocks the sender, receiving from an empty channel blocks the receiver.
  42. Goroutines are indipendent executing actors communicating via channels De netely

    easier to reason about
  43. An example package main import "fmt" func main() { source

    := make(chan int) incremented := make(chan int) go func() { for i := 0; i < 100; i++ { source <- i } close(source) }() go func() { for s := range source { incremented <- s + 1000 } close(incremented) }() for res := range incremented { fmt.Println(res) } } Run
  44. Where are my mutexes?

  45. Go provides synchronization primitives Mutexes RW Locks sync.Once

  46. Everything else

  47. Coding style Survey by stackover ow (https://stackover ow.blog/2017/06/15/developers-use-spaces-make-money-use-tabs/) Go fmt

    formats the code in the "go way" easier to read easier to write no tabs vs spaces discussions!
  48. Building Workspace: root tree pointed by $GOPATH variable bin/ hello

    # command executable pkg/ linux_amd64/ github.com/fedepaol/example/ stringutil.a # package object src/ github.com/fedepaol/example/ hello/ hello.go # command source stringutil.go golang.org/x/image/ bmp/ reader.go # package source writer.go # package source Most Go programmers keep all their Go source code and dependencies in a single workspace
  49. Building (2) go build package non main packages are compiled

    and thrown away executables are compiled and left in the current dir go install package non main packages are deployed in $GOPATH/pkg executables in $GOPATH/bin go get package (as in github.com/fedepaol/example/hello) downloads the package and its dependencies installs it
  50. Deploying There is no need for shared libraries. Not even

    libc. The go runtime is linked together with the executable. The absence of external dependencies makes the deployement a lot easier than a C executable.
  51. There's more! re ection race detector C interoperability rich standard

    library awesome echosystem (https://github.com/avelino/awesome-go) integrated testing framework native cpu and memory pro ling cross compiles awesome linters
  52. What I did expect from Go

  53. Doing a lot with few lines of code Javascript var

    result = tasks.map(function (task) { return (task.duration / 60); }).filter(function (duration) { return duration >= 2; }); Java Arrays.stream(myArray) .filter(s -> s.length() > 4) .map(s -> s.toUpperCase()) .toArray(String[]::new); Kotlin strings.filter { it.length == 5 }.sortedBy { it }.map { it.toUpperCase() }
  54. What I found Go focuses on being explicit rather than

    implicit being readable being safe getting sh*t done
  55. Where to go from here O cial website golang.org (http://golang.org)

    Interactive Tutorial tour.golang.org (http://tour.golang.org) E ective go golang.org/doc/e ective_go.html (https://golang.org/doc/e ective_go.html) Mailing list groups.google.com/forum/#%21forum/golang-nuts (https://groups.google.com/forum/#%21forum/golang-nuts)
  56. Thank you Federico Paolinelli List @fedepaol (http://twitter.com/fedepaol) fedepaol@gmail.com (mailto:fedepaol@gmail.com)

  57. None