europython 2016 - do i need to switch to golang

40
1 / 40 Do I need to switch to Go(lang) Max Tepkeev 20 July 2016 Bilbao, Spain

Upload: max-tepkeev

Post on 13-Jan-2017

257 views

Category:

Software


1 download

TRANSCRIPT

Page 1: EuroPython 2016 - Do I Need To Switch To Golang

1 / 40

Do I need to switchto Go(lang)Max Tepkeev20 July 2016Bilbao, Spain

Page 2: EuroPython 2016 - Do I Need To Switch To Golang

2 / 40

About me

Max TepkeevRussia, Moscow

• python-redmine• architect• instructions

https://www.github.com/maxtepkeev

Page 3: EuroPython 2016 - Do I Need To Switch To Golang

3 / 40

About us

Aidata – online and offline user data collection and analysis

1 000 000 000unique users per month

http://www.aidata.me

Page 4: EuroPython 2016 - Do I Need To Switch To Golang

4 / 40

About us

Page 5: EuroPython 2016 - Do I Need To Switch To Golang

5 / 40

Why switch from Python

• Speed• Concurrency• GIL• No ”true” binaries• Dynamic types

Page 6: EuroPython 2016 - Do I Need To Switch To Golang

6 / 40

Language requirements

• Modern• Fast• Easy• Compiled• Statically typed• Support main platforms

Page 7: EuroPython 2016 - Do I Need To Switch To Golang

7 / 40

Why Go

StackOverflow questions by tag*:

• Go: 16795 (1113)• Rust: 4226 (429)• D: 2025 (34)• Nim: 136 (8)

* as of 19 July 2016

Page 8: EuroPython 2016 - Do I Need To Switch To Golang

8 / 40

Popularity

Page 9: EuroPython 2016 - Do I Need To Switch To Golang

9 / 40

Go

• Created in Google• Open-sourced in November 2009• Designed by smart people:• Robert Griesemer• Rob Pike• Ken Thompson

https://talks.golang.org/2012/splash.article

Page 10: EuroPython 2016 - Do I Need To Switch To Golang

10 / 40

Who uses Go

• Google• Dropbox• Facebook• IBM• Intel• SpaceX

• Uber• VMware• Yahoo• Twitter• Heroku• DigitalOcean

https://github.com/golang/go/wiki/GoUsers

Page 11: EuroPython 2016 - Do I Need To Switch To Golang

11 / 40

Project layout$GOPATH/ bin/ hello # command executable outyet # command executable pkg/ linux_amd64/ github.com/golang/example/ stringutil.a # package object src/ github.com/golang/example/ .git/ # Git repository metadata hello/ hello.go # command source outyet/ main.go # command source stringutil/ reverse.go # package source

Page 12: EuroPython 2016 - Do I Need To Switch To Golang

12 / 40

Package management$ go get github.com/golang/example

src/ github.com/golang/example/ .git/ hello/ hello.go outyet/ main.go stringutil/ reverse.go

Page 13: EuroPython 2016 - Do I Need To Switch To Golang

13 / 40

Package management• vendoring• gopkg.in• getgb.io

github.com/tools/godepgithub.com/gpmgo/gopmgithub.com/pote/gpmgithub.com/nitrous-io/goopgithub.com/alouche/rodentgithub.com/jingweno/nutgithub.com/niemeyer/gopkggithub.com/mjibson/partygithub.com/kardianos/vendorgithub.com/kisielk/vendorizegithub.com/mattn/gom

github.com/dkulchenko/bunchgithub.com/skelterjohn/wgogithub.com/Masterminds/glidegithub.com/robfig/glockbitbucket.org/vegansk/gobslaunchpad.net/godepsgithub.com/d2fn/gopackgithub.com/laher/gopingithub.com/LyricalSecurity/gigogithub.com/VividCortex/johnny-deps

Page 14: EuroPython 2016 - Do I Need To Switch To Golang

14 / 40

Commands• go fmt• go test• go fix• go run• go run -race• go vet

Page 15: EuroPython 2016 - Do I Need To Switch To Golang

15 / 40

Hello World$GOPATH/src/github.com/user/hello/hello.go:

package main

import "fmt"

func main() { fmt.Println("Hello, world.")}

$ go install github.com/user/hello$ $GOPATH/bin/helloHello, world.

Page 16: EuroPython 2016 - Do I Need To Switch To Golang

16 / 40

Comparison: Imports

Go

import "os"

import ( "os" "compress/gzip")

import os1 "os"

Python

import os

import osimport gzip

import os as os1

Page 17: EuroPython 2016 - Do I Need To Switch To Golang

17 / 40

Comparison: Import Names

Go

import "os"

os.Getwd()

Python

import os

os.getcwd()

Page 18: EuroPython 2016 - Do I Need To Switch To Golang

18 / 40

Comparison: Types

Govar ( b bool = true s string = "hey" si int = -1 ui uint = 1 f float32 = 1.0 c complex64 = 3i l []int = []int{1, 2} m map[int]int = map[int]int{1: 1})

Python

b = Trues = "hey"si = 1ui = -1f = 1.0c = 3jl = [1, 2]m = {1:1}

Page 19: EuroPython 2016 - Do I Need To Switch To Golang

19 / 40

Comparison: Variables

Go

var ( i = 1 j = "hey")

i := 1j := "hey”

i, j := 1, "hey"

Python

i = 1j = "hey”

i, j = 1, "hey"

Page 20: EuroPython 2016 - Do I Need To Switch To Golang

20 / 40

Comparison: 1st Class Functions

Go

func add(x, y int) int { return x + y}

add := func (x, y int) int { return x + y}

Python

def add(x, y): return x + y

add = lambda x, y: x + y

Page 21: EuroPython 2016 - Do I Need To Switch To Golang

21 / 40

Comparison: Optional args

Go

func sum(nums ...int) { result := 0 for _, num := range nums { result += num } return result}sum(1, 2, 3)sum([]int{1, 2, 3}...)

Python

def sum(*nums): result = 0 for num in nums: result += num return result

sum(1, 2, 3)sum(*[1, 2, 3])

Page 22: EuroPython 2016 - Do I Need To Switch To Golang

22 / 40

Comparison: Optional kwargs

Gotype Kwargs struct { foo, bar string}

func join(kw Kwargs) string { if kw.foo == "" {kw.foo = "foo"} if kw.bar == "" {kw.bar = "bar"} return kw.foo + kw.bar}

join(Kwargs{})join(Kwargs{bar: "foo"})

Pythondef join(foo=None, bar=None): if foo is None: foo = 'foo' if bar is None: bar = 'bar' return foo + bar

join()join(bar='foo')

Page 23: EuroPython 2016 - Do I Need To Switch To Golang

23 / 40

Comparison: Loops

Go

seq := []int{1, 2, 3}for _, x := range seq { fmt.Println(x)}

Python

seq = [1, 2, 3]for x in seq: print x

Page 24: EuroPython 2016 - Do I Need To Switch To Golang

24 / 40

Comparison: Loops

Go

seq := []int{1, 2, 3}

for i := 0; i < len(seq); i++ { fmt.Println(seq[i])}

Python

seq = [1, 2, 3]num, count = 0, len(seq)

while num < count: print seq[num] num += 1

Page 25: EuroPython 2016 - Do I Need To Switch To Golang

25 / 40

Comparison: Loops

Go

for { fmt.Println("Go rocks")}

Python

while True: print "Python rocks"

Page 26: EuroPython 2016 - Do I Need To Switch To Golang

26 / 40

Comparison: Comprehensions

Goword := "hello"chars := []string{}for _, char := range word { chars = append(chars, string(char))}fmt.Println(chars) // [h e l l o]

Pythonword = "hello"chars = [char for char in word]print chars # ['h', 'e', 'l', 'l', 'o']

Page 27: EuroPython 2016 - Do I Need To Switch To Golang

27 / 40

Comparison: Conditionals

Go

if x := 1; x > 0 { fmt.Println(x)} else { fmt.Println("Sorry")}

Python

x = 1if x > 0: print xelse: print "Sorry"

Page 28: EuroPython 2016 - Do I Need To Switch To Golang

28 / 40

Comparison: Conditionals

Go

switch x := 1; {case x < 0: fmt.Println("Negative")case x > 0: fmt.Println("Positive")default: fmt.Println("Zero")}

Python

x = 1if x > 0: print "Positive"elif x < 0: print "Negative"else: print "Zero"

Page 29: EuroPython 2016 - Do I Need To Switch To Golang

29 / 40

Comparison: Slicing

Go

seq := []int{1, 2, 3, 4, 5}fmt.Print(seq[:2]) // [1 2]fmt.Print(seq[3:]) // [4 5]fmt.Print(seq[2:3]) // [3]

Python

seq = [1, 2, 3, 4, 5]print seq[:2] # [1, 2]print seq[3:] # [4, 5]print seq[2:3] # [3]

Page 30: EuroPython 2016 - Do I Need To Switch To Golang

30 / 40

Comparison: Error Handling

Go

conn, err := db.Connect()if err != nil { fmt.Print("Can't connect")}

panic() / recover()

Python

try: conn = db.Connect()except ConnectionError: print "Can't connect"

Page 31: EuroPython 2016 - Do I Need To Switch To Golang

31 / 40

Comparison: Classes

Gotype Person struct { Name string Age int}

func (p Person) String() string { return fmt.Sprintf( "%s: %d", p.Name, p.Age)}

p := Person{"Batman", 45}fmt.Println(p) // Batman: 45

Pythonclass Person(object): def __init__(self, name, age): self.name = name self.age = age

def __str__(self): return "{}: {}".format( self.name, self.age)

p = Person("Batman", 45)print p # Batman: 45

Page 32: EuroPython 2016 - Do I Need To Switch To Golang

32 / 40

Comparison: Constructors

Gotype Person struct { Name string Age int}

func NewPerson(n string, a int) *Person { return &Person{Name: n, Age: a}}

p := NewPerson("Batman", 45)

Pythonclass Person(object): def __init__(self, name, age): self.name = name self.age = age

p = Person("Batman", 45)

Page 33: EuroPython 2016 - Do I Need To Switch To Golang

33 / 40

Comparison: Inheritance

Gotype Person struct{ Name string }type Doctor struct{ Person }

func (p Person) Eat() { fmt.Println("Eating")}

func (d Doctor) Heal() { fmt.Println("Healing")}

d := Doctor{Person{"Gregory House"}}d.Eat() // Eatingd.Heal() // Healing

Pythonclass Person(object): def __init__(self, name): self.name = name def eat(self): print "Eating"

class Doctor(Person): def heal(self): print "Healing"

d = Doctor("Gregory House")d.eat() # "Eating"d.heal() # "Healing"

Page 34: EuroPython 2016 - Do I Need To Switch To Golang

34 / 40

Comparison: Cleanup

Gofunc readFile() (result string) { fpath := "/tmp/file" f, err := os.Open(fpath) if err != nil { panic(err) } defer f.Close() // reading file here return result}

Pythondef read_file(): result = None fpath = "/tmp/file" with open(fpath) as f: result = f.read() # file is closed here return result

Page 35: EuroPython 2016 - Do I Need To Switch To Golang

35 / 40

Comparison: Concurrent progsGo

urls := []string{"http://python.org", "http://golang.org"}

responses := make(chan string)

for _, url := range urls { go func(url string) { resp, _ := http.Get(url) defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) responses <- string(body) }(url)}

for response := range responses { fmt.Println(response)}

Pythonurls = ['http://python.org', 'http://golang.org']

async def fetch(session, url): async with session.get(url) as response: return await response.read()

async def fetch_all(session, urls, loop): tasks = [fetch(session, url) for url in urls] return await asyncio.gather(*tasks)

loop = asyncio.get_event_loop()

with aiohttp.ClientSession(loop=loop) as session: responses = loop.run_until_complete( fetch_all(session, urls, loop))

print(responses)

Page 36: EuroPython 2016 - Do I Need To Switch To Golang

36 / 40

More Go features• make() / new()• Arrays• Pointers• Interfaces• Type assertions• Type switches• Buffered channels / select statement• Unsafe package• Cross compilation

Page 37: EuroPython 2016 - Do I Need To Switch To Golang

37 / 40

Python features Go lacks• list / dict comprehensions• generators• decorators• exceptions• metaclasses• descriptors• __magic__ methods• set / tuple

Page 38: EuroPython 2016 - Do I Need To Switch To Golang

38 / 40

Conclusion

Go+ Good standard library+ 3rd Party libs for almost everything+ Compiled+ Statically typed+ Built-in concurrency

- Verbose- No syntactic sugar- No Soul

Python+ Good standard library+ 3rd Party libs for everything+ Less code+ Syntactic sugar+ Has Soul

- Interpreted- Dynamically typed- Concurrency

Page 39: EuroPython 2016 - Do I Need To Switch To Golang

39 / 40

Go Useful Links1. https://tour.golang.org/2. http://golang.org/doc/effective_go.html3. https://play.golang.org/4. http://golangweekly.com/5. http://devs.cloudimmunity.com/gotchas-

and-common-mistakes-in-go-golang/

Page 40: EuroPython 2016 - Do I Need To Switch To Golang

40 / 40

Questions

slides: http://slideshare.net/maxtepkeev

github: https://github.com/maxtepkeevemail: [email protected]: max.tepkeevcompany: http://www.aidata.me