commit 5783dd7f09d35b1052b0b77d12f894ae5a436295 Author: Vincent Batts Date: Fri Feb 6 00:58:25 2015 +0100 2015 diff --git a/2015/02-devconf.cz/cats20.gif b/2015/02-devconf.cz/cats20.gif new file mode 100644 index 0000000..b6c353a Binary files /dev/null and b/2015/02-devconf.cz/cats20.gif differ diff --git a/2015/02-devconf.cz/gopher.png b/2015/02-devconf.cz/gopher.png new file mode 100644 index 0000000..cb5e2e1 Binary files /dev/null and b/2015/02-devconf.cz/gopher.png differ diff --git a/2015/02-devconf.cz/kanye_imma_bookmarklet.png b/2015/02-devconf.cz/kanye_imma_bookmarklet.png new file mode 100644 index 0000000..e896826 Binary files /dev/null and b/2015/02-devconf.cz/kanye_imma_bookmarklet.png differ diff --git a/2015/02-devconf.cz/rainbow.jpg b/2015/02-devconf.cz/rainbow.jpg new file mode 100644 index 0000000..eb3c98e Binary files /dev/null and b/2015/02-devconf.cz/rainbow.jpg differ diff --git a/2015/02-devconf.cz/revenge-of-the-nerds-o.gif b/2015/02-devconf.cz/revenge-of-the-nerds-o.gif new file mode 100644 index 0000000..fce49b6 Binary files /dev/null and b/2015/02-devconf.cz/revenge-of-the-nerds-o.gif differ diff --git a/2015/02-devconf.cz/talk.slide b/2015/02-devconf.cz/talk.slide new file mode 100644 index 0000000..c72ac61 --- /dev/null +++ b/2015/02-devconf.cz/talk.slide @@ -0,0 +1,170 @@ +Golang - the good, the bad, the ugly +06 Feb 2015 - devconf.cz + +Vincent Batts +Developer +@vbatts +vbatts@redhat.com + +* howdy + +$> whoami +vbatts +$> id -Gn +vbatts devel openshift docker + +* golang + +## Notes +# - libraries - source only, but can link to C *.so and *.a +# - Fork/Exec are coupled together (for coroutine and GC reasons) +# - Threading, and multiproc, concurrent logic +# -- nice and easy to use +# -- Make for tricky handling of C calls (i.e. setns) +# - `go get` is handy +# - cross-compile without hardly any bootstrapping +# -- native compiler supported arches +# -- gccgo works for the arch gcc is compiled for +# - primitives can seem a bit magical +# -- conditional returns +# -- for ... range +# -- iota +# - no ifdefs, but build tags +# - error handling, rather than exception catching + +* + +.image ./gopher.png + +* Overview + +- strongly typed +- compiled +- stylistically nice +- opinionated + +* Good + +* + +.image ./rainbow.jpg + +* fully qualified imports + +.code ./talk/imports.go /START1/,/STOP1/ + +* fast compiles + +(Perhaps other compilers are slow) + +.play ./talk/hello.go /START1/,/STOP1/ + +* defer + +.code ./talk/good0.go /START1/,/STOP1/ + +* Garbage Collected + +- Super convenient +- references +- completed goroutines + +* simple exports + +.code ./talk/good1.go /START1/,/STOP1/ + +* concurrency + +.play ./talk/pingpong.go /STARTMAIN1/,/STOPMAIN1/ +.link http://talks.golang.org/2013/advconc.slide Sameer Ajmani - Advanced Concurrency + +* +.image ./kanye_imma_bookmarklet.png 320 _ + +- easy learning curve +- `go get` +- cross-compiles + + +* Bad + +* + +# they come along, and affect how you do your work +.image ./cats20.gif + +* lack of generics? +# i don't feel strongly about this, though many do +- interfaces - are enough for most +- go1.4 introduced go:generate +# produce code for Set, Graph etc, for the types needed, but at compile time. No need to reflect. + +* Debugging + +- gdb is there, sort of +- some known debugging tools for ELF are not useful +- fmt.Printf("%#v\n", ...) + +* Concurrency and GC + +Calls like setns(2) are rough + + +(yes, even with runtime.LockOSThread()) + +* Fork/Exec + +Not Separate, but together + +* Ugly? (maybe just new) + +* +.image ./revenge-of-the-nerds-o.gif + +* build tags + +.code ./talk/tags.go /START1/,/STOP1/ + +or files with *_linux.go like suffix + +* _ + +bit bucket + +* channels + +.play ./talk/ugly0.go /START1/,/STOP1/ + +* iota + +.code ./talk/ugly1.go /START1/,/STOP1/ + +* for range + +array (or string) + +.play ./talk/primitive1.go /START1/,/STOP1/ + +* for range + +map + +.play ./talk/primitive2.go /START1/,/STOP1/ + +* for range + +channel (like an iterator) + +.play ./talk/primitive3.go /START1/,/STOP1/ + +* for range + +channel + +.code ./talk/primitive3.go /START2/,/STOP2/ + +* Conclusions? + +* use-case + +- like all languages, align with you use-case diff --git a/2015/02-devconf.cz/talk/good0.go b/2015/02-devconf.cz/talk/good0.go new file mode 100644 index 0000000..3a3b880 --- /dev/null +++ b/2015/02-devconf.cz/talk/good0.go @@ -0,0 +1,48 @@ +// +build ignore + +package main + +import ( + "compress/gzip" + "encoding/json" + "flag" + "io/ioutil" + "log" + "os" +) + +func main() { + for _, arg := range flag.Args() { + func() { + // START1 OMIT + fh, err := os.Open(arg) + if err != nil { + log.Fatal(err) + } + defer fh.Close() + + gz, err := gzip.NewReader(fh) + if err != nil { + log.Fatal(err) + } + defer gz.Close() + + buf, err := ioutil.ReadAll(gz) + if err != nil { + log.Fatal(err) + } + + var mine MyStruct + err = json.Unmarshal(&mine) + if err != nil { + log.Fatal(err) + } + // STOP1 OMIT + + }() + } + +} + +type MyStruct struct { +} diff --git a/2015/02-devconf.cz/talk/good1.go b/2015/02-devconf.cz/talk/good1.go new file mode 100644 index 0000000..84a3b6e --- /dev/null +++ b/2015/02-devconf.cz/talk/good1.go @@ -0,0 +1,20 @@ +// +build ignore + +package main + +// START1 OMIT +// exported +type Foo struct { + Bar string // exported + baz bool // private +} + +// private +type bif struct { + Harf, Buz int64 // doesn't matter +} + +// STOP1 OMIT + +func main() { +} diff --git a/2015/02-devconf.cz/talk/hello.go b/2015/02-devconf.cz/talk/hello.go new file mode 100644 index 0000000..8ad6d97 --- /dev/null +++ b/2015/02-devconf.cz/talk/hello.go @@ -0,0 +1,10 @@ +// +build ignore + +// START1 OMIT +package main + +func main() { + println("Howdy y'all") +} + +// STOP1 OMIT diff --git a/2015/02-devconf.cz/talk/imports.go b/2015/02-devconf.cz/talk/imports.go new file mode 100644 index 0000000..ba18875 --- /dev/null +++ b/2015/02-devconf.cz/talk/imports.go @@ -0,0 +1,18 @@ +// +build ignore + +package main + +// START1 OMIT +import ( + "fmt" + "os" + + "github.com/foo/bar" +) + +// STOP1 OMIT + +func main() { + fmt.Println(bar.Baz()) + _ = os.FileInfo +} diff --git a/2015/02-devconf.cz/talk/pingpong.go b/2015/02-devconf.cz/talk/pingpong.go new file mode 100644 index 0000000..159d2c5 --- /dev/null +++ b/2015/02-devconf.cz/talk/pingpong.go @@ -0,0 +1,33 @@ +// +build OMIT + +package main + +import ( + "fmt" + "time" +) + +// STARTMAIN1 OMIT +type Ball struct{ hits int } + +func main() { + table := make(chan *Ball) + go player("ping", table) + go player("pong", table) + + table <- new(Ball) // game on; toss the ball + time.Sleep(1 * time.Second) + <-table // game over; grab the ball +} + +func player(name string, table chan *Ball) { + for { + ball := <-table + ball.hits++ + fmt.Println(name, ball.hits) + time.Sleep(100 * time.Millisecond) + table <- ball + } +} + +// STOPMAIN1 OMIT diff --git a/2015/02-devconf.cz/talk/primitive1.go b/2015/02-devconf.cz/talk/primitive1.go new file mode 100644 index 0000000..d9e1961 --- /dev/null +++ b/2015/02-devconf.cz/talk/primitive1.go @@ -0,0 +1,25 @@ +// +build ignore + +package main + +import "fmt" + +func main() { + // START1 OMIT + names := []string{ + "Michael", + "Jan", + "Sean", + "Silvia", + } + for i, name := range names { + fmt.Printf("%q is the %d name\n", name, i) + } + for i := range names { + fmt.Printf("%q is the %d name\n", names[i], i) + } + for _, name := range names { + fmt.Printf("%q is the ... name\n", name) + } + // STOP1 OMIT +} diff --git a/2015/02-devconf.cz/talk/primitive2.go b/2015/02-devconf.cz/talk/primitive2.go new file mode 100644 index 0000000..9d54624 --- /dev/null +++ b/2015/02-devconf.cz/talk/primitive2.go @@ -0,0 +1,56 @@ +// +build ignore + +package main + +import "fmt" + +func main() { + // START1 OMIT + infos := map[string]Info{ + "Michael": Info{ + City: "Happyville", + Status: Open, + }, + "Jan": Info{ + City: "Confusville", + Status: Closed, + }, + "Sean": Info{ + City: "Septober", + Status: Complicated, + }, + "Silvia": Info{ + City: "Curiousville", + Status: Curios, + }, + } + for name, info := range infos { + fmt.Printf("%q is %s in %q\n", name, info.Status, info.City) + } + // STOP1 OMIT +} + +type Info struct { + City string + Status Status +} +type Status int + +var ( + Open = Status(0) + Closed = Status(1) + Complicated = Status(2) + Curios = Status(3) +) + +func (s Status) String() string { + switch s { + case Open: + return "open" + case Closed: + return "closed" + case Complicated: + return "complicated" + } + return "hurr" +} diff --git a/2015/02-devconf.cz/talk/primitive3.go b/2015/02-devconf.cz/talk/primitive3.go new file mode 100644 index 0000000..c3329d5 --- /dev/null +++ b/2015/02-devconf.cz/talk/primitive3.go @@ -0,0 +1,37 @@ +// +build ignore + +package main + +import "fmt" + +func main() { + // START1 OMIT + fmt.Println("I've got:") + for card := range ReadEmAndWeep() { + fmt.Printf(" %s of %s\n", card.Value, card.Suite) + } + // STOP1 OMIT +} + +type Card struct { + Suite, Value string +} + +// START2 OMIT +func ReadEmAndWeep() <-chan Card { + c := make(chan Card) + go func() { + for _, card := range []Card{ + Card{"Ace", "Jack"}, + Card{"Ace", "Queen"}, + Card{"Ace", "King"}, + Card{"Ace", "Ace"}, + } { + c <- card + } + close(c) + }() + return c +} + +// STOP2 OMIT diff --git a/2015/02-devconf.cz/talk/tags.go b/2015/02-devconf.cz/talk/tags.go new file mode 100644 index 0000000..6e89e71 --- /dev/null +++ b/2015/02-devconf.cz/talk/tags.go @@ -0,0 +1,8 @@ +// START1 OMIT +// +build !windows linux,cgo +// STOP1 OMIT + +package main + +func main() { +} diff --git a/2015/02-devconf.cz/talk/ugly0.go b/2015/02-devconf.cz/talk/ugly0.go new file mode 100644 index 0000000..715c384 --- /dev/null +++ b/2015/02-devconf.cz/talk/ugly0.go @@ -0,0 +1,16 @@ +// +build ignore + +package main + +func main() { + // START1 OMIT + c := make(chan int) + go func() { + for i := 0; i < 10; i++ { + c <- i + } + close(c) + }() + println(<-c) + // STOP1 OMIT +} diff --git a/2015/02-devconf.cz/talk/ugly1.go b/2015/02-devconf.cz/talk/ugly1.go new file mode 100644 index 0000000..3d72e71 --- /dev/null +++ b/2015/02-devconf.cz/talk/ugly1.go @@ -0,0 +1,22 @@ +// +build ignore + +package main + +// START1 OMIT +const ( + DeviceCreate TaskType = iota + DeviceReload + DeviceRemove + DeviceRemoveAll + DeviceSuspend + DeviceResume + DeviceInfo + DeviceDeps +) + +// STOP1 OMIT + +type TaskType int + +func main() { +} diff --git a/2015/2015-02-01 - Centos Brussels - vbatts - atomic,kubernetes,docker.odp b/2015/2015-02-01 - Centos Brussels - vbatts - atomic,kubernetes,docker.odp new file mode 100644 index 0000000..df26746 Binary files /dev/null and b/2015/2015-02-01 - Centos Brussels - vbatts - atomic,kubernetes,docker.odp differ diff --git a/2015/2015-02-01 - FOSDEM - vbatts - containers.odp b/2015/2015-02-01 - FOSDEM - vbatts - containers.odp new file mode 100644 index 0000000..703a4f6 Binary files /dev/null and b/2015/2015-02-01 - FOSDEM - vbatts - containers.odp differ