Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go for Pythonistas

Go for Pythonistas

An overview of the Go programming language from the point of view of a seasoned Python developer.
golang, python

Francesc Campoy Flores

September 12, 2014
Tweet

More Decks by Francesc Campoy Flores

Other Decks in Programming

Transcript

  1. My tactics 1. Showing you how Go is like Python.

    2. Showing you how Go is not like Python.
  2. Python, Go, and me Software Engineer at Google: Feb 11-Aug

    12 Lots of C++ and Python. SQL to C++ compiler in Python. Go Developer Relations: Aug 12 - d a t e t i m e . n o w ( ) Lots of Go.
  3. Beautiful and simple Dynamic typing - nice because it's concise,

    like Python. a = " h e l l o " b = 1 # b u t a l s o a = 2 Static typing - can be verbose, like Java or C++. F o o f o o = n e w F o o ( ) ; Static typing with inferred types, like Go. a : = " h e l l o " b : = 1 / / b u t n o a = 2 Statically-typed Python? Check mypy (http://www.mypy-lang.org/) and Cython (http://cython.org/) .
  4. Run time pyrotechnics n a m e = ' p

    y t h o n i s t a ' # T h i s c o d e o n l y w o r k s h a l f o f t h e t i m e . i f r a n d o m . r a n d o m ( ) > 0 . 5 : p r i n t ' h e y ' + n a m e + ' , y o u w i n ! ' e l s e : p r i n t ' s o r r y ' + n a n e + ' , y o u l o s e ' I don't want start a flame war here but ... 100% code coverage is a symptom Code coverage should point you to untested cases. Not a way to find typos! 100% code coverage doesn't mean bug free.
  5. Other things I don't like Deploying - managing dependencies. Performance

    - "not too slow" is often not fast enough. Magic! (e.g.: _ _ m a g i c _ _ : * * k a r g s , _ _ g e t a t t r _ _ ) A list of magic methods in Python: www.rafekettler.com/magicmethods.html (http://www.rafekettler.com/magicmethods.html)
  6. And I *do* like concurrency! A lot has been said

    about Python's infamous Global Interpreter Lock. You should watch Mindblowing Python GIL (http://youtu.be/ph374fJqFPE) , by David Beazley.
  7. Things I like about Python The Zen of Python. (Go

    and the Zen of Python (http://talks.golang.org/2012/zen.slide#1) ) Hashes and arrays are part of the language. The standard library. Magic! A bit of code can do a lot.
  8. fib.py Have you ever heard of Fibonacci? d e f

    f i b ( n ) : a , b = 0 , 1 f o r i i n r a n g e ( n ) : a , b = b , a + b r e t u r n b d e f f i b _ r e c ( n ) : i f n < = 1 : r e t u r n 1 e l s e : r e t u r n f i b _ r e c ( n - 1 ) + f i b _ r e c ( n - 2 ) f o r x i n r a n g e ( 1 0 ) : p r i n t f i b ( x ) , f i b _ r e c ( x )
  9. fib.go Something familiar? f u n c f i b

    ( n i n t ) i n t { a , b : = 0 , 1 f o r i : = 0 ; i < n ; i + + { a , b = b , a + b } r e t u r n b } f u n c f i b R e c ( n i n t ) i n t { i f n < = 1 { r e t u r n 1 } r e t u r n f i b R e c ( n - 1 ) + f i b R e c ( n - 2 ) } f u n c m a i n ( ) { f o r i : = 0 ; i < 1 0 ; i + + { f m t . P r i n t l n ( f i b ( i ) , f i b R e c ( i ) ) } } Run
  10. Fibonacci without generators? What? Python generators are awesome. d e

    f f i b ( n ) : a , b = 0 , 1 f o r i i n r a n g e ( n ) : a , b = b , a + b y i e l d a Mechanically complex. f = f i b ( 1 0 ) t r y : w h i l e T r u e : p r i n t f . n e x t ( ) e x c e p t S t o p I t e r a t i o n : p r i n t ' d o n e ' But very easy to use. f o r x i n f i b ( 1 0 ) : p r i n t x p r i n t ' d o n e '
  11. Go concurrency Based on goroutines and channels. Goroutines: very light

    processing actors (the gophers). Channels: typed, synchronized, thread-safe pipes (the arrows).
  12. "Generator" goroutines Uses a channel send instead of y i

    e l d . f u n c f i b ( c c h a n i n t , n i n t ) { a , b : = 0 , 1 f o r i : = 0 ; i < n ; i + + { a , b = b , a + b c < - a } c l o s e ( c ) } f u n c m a i n ( ) { c : = m a k e ( c h a n i n t ) g o f i b ( c , 1 0 ) f o r x : = r a n g e c { f m t . P r i n t l n ( x ) } } Run
  13. "Generator" goroutines A more generator-like style: f u n c

    f i b ( n i n t ) c h a n i n t { c : = m a k e ( c h a n i n t ) g o f u n c ( ) { a , b : = 0 , 1 f o r i : = 0 ; i < n ; i + + { a , b = b , a + b c < - a } c l o s e ( c ) } ( ) r e t u r n c } f u n c m a i n ( ) { f o r x : = r a n g e f i b ( 1 0 ) { f m t . P r i n t l n ( x ) } } Run
  14. Exercise: generating prime numbers Write a function that returns a

    channel and sends the first n prime numbers on it. Given the function p r i m e : / / p r i m e r e t u r n s t r u e i f n i s a p r i m e n u m b e r . f u n c p r i m e ( n i n t ) b o o l { f o r i : = 2 ; i < n ; i + + { i f n % i = = 0 { r e t u r n f a l s e } } r e t u r n t r u e } Use the Go playground: golang.org/s/go4py-ex1 (http://golang.org/s/go4py-ex1)
  15. Solution: generating prime numbers f u n c p r

    i m e s ( n i n t ) c h a n i n t { c : = m a k e ( c h a n i n t ) g o f u n c ( ) { f o r i : = 1 ; n > 0 ; i + + { i f p r i m e ( i ) { c < - i n - - } } c l o s e ( c ) } ( ) r e t u r n c } f u n c m a i n ( ) { f o r p : = r a n g e p r i m e s ( 1 0 ) { f m t . P r i n t l n ( p ) } } Run
  16. Exercise: Fibonacci primes Write a f i l t e

    r P r i m e s function that takes a channel of ints as a parameter and returns another channel of ints. All the prime numbers that f i l t e r P r i m e s receives from the input channel are sent into the output channel. Complete this code snippet: golang.org/s/go4py-ex2 (http://golang.org/s/go4py-ex2)
  17. Solution: Fibonacci primes f u n c f i l

    t e r P r i m e s ( c i n c h a n i n t ) c h a n i n t { c o u t : = m a k e ( c h a n i n t ) g o f u n c ( ) { f o r v : = r a n g e c i n { i f p r i m e ( v ) { c o u t < - v } } c l o s e ( c o u t ) } ( ) r e t u r n c o u t } f u n c m a i n ( ) { f o r p : = r a n g e f i l t e r P r i m e s ( f i b ( 2 0 ) ) { f m t . P r i n t l n ( p ) } } Run
  18. But there's much more Goroutines and channels aren't just for

    generators. They can be used to model all kinds of concurrent systems. To learn more: Concurrency patterns (http://talks.golang.org/2012/concurrency.slide#1) , by Rob Pike Advanced Concurrency Patterns (http://talks.golang.org/2013/advconc.slide#1) , by Sameer Ajmani
  19. Object-oriented Go A type declaration. t y p e N

    a m e s t r u c t { F i r s t s t r i n g M i d d l e s t r i n g L a s t s t r i n g } A method declaration. f u n c ( n N a m e ) S t r i n g ( ) s t r i n g { r e t u r n f m t . S p r i n t f ( " % s % c . % s " , n . F i r s t , n . M i d d l e [ 0 ] , s t r i n g s . T o U p p e r ( n . L a s t ) ) } Constructing a N a m e and using it. n : = N a m e { " W i l l i a m " , " M i k e " , " S m i t h " } f m t . P r i n t f ( " % s " , n . S t r i n g ( ) ) Run
  20. Methods on anything There's more to types than structs. t

    y p e S i m p l e N a m e s t r i n g You can define methods on any type. f u n c ( s S i m p l e N a m e ) S t r i n g ( ) s t r i n g { r e t u r n s t r i n g ( s ) } Or almost any type. f u n c ( s s t r i n g ) N o W a y ( ) You can only define methods on types within the same package.
  21. Duck typing If it walks like a duck ... What

    defines a duck? Is there an explicit list of "duck" features? What if the duck is not exactly a duck? s/duck/file-like object/g
  22. Go interfaces Simply a set of methods. From the f

    m t package: t y p e S t r i n g e r i n t e r f a c e { S t r i n g ( ) s t r i n g } f m t . P r i n t l n calls the String method if the parameter is a S t r i n g e r . A type with all the methods of the interface implements the interface. Implicit satisfaction == No "implements" Structural typing: it doesn't just sound like a duck, it is a duck. And that's checked at compile time. n = N a m e { " W i l l i a m " , " M i k e " , " S m i t h " } f m t . P r i n t l n ( n ) Run
  23. Decorators A convenient way to wrap a function. d e

    f a u t h _ r e q u i r e d ( m y f u n c ) : d e f c h e c k u s e r ( s e l f ) : u s e r = p a r s e _ q s ( u r l p a r s e ( s e l f . p a t h ) . q u e r y ) . g e t ( ' u s e r ' ) i f u s e r : s e l f . u s e r = u s e r [ 0 ] m y f u n c ( s e l f ) e l s e : s e l f . w f i l e . w r i t e ( ' u n k n o w n u s e r ' ) r e t u r n c h e c k u s e r A function can be decorated using @ . c l a s s m y H a n d l e r ( B a s e H T T P R e q u e s t H a n d l e r ) : @ a u t h _ r e q u i r e d d e f d o _ G E T ( s e l f ) : s e l f . w f i l e . w r i t e ( ' H e l l o , % s ! ' % s e l f . u s e r )
  24. Decorators If we run it. t r y : s

    e r v e r = H T T P S e r v e r ( ( ' ' , P O R T _ N U M B E R ) , m y H a n d l e r ) s e r v e r . s e r v e _ f o r e v e r ( ) e x c e p t K e y b o a r d I n t e r r u p t : s e r v e r . s o c k e t . c l o s e ( ) This is unauthorized: localhost:8080/hi (http://localhost:8080/hi) This is authorized: localhost:8080/hi?user=john (http://localhost:8080/hi?user=john)
  25. Decorators in Go? Not exactly, but close enough. Go doesn't

    provide decorators in the language, but its function literal syntax and simple scoping rules make it easy to do something similar. v a r h i H a n d l e r = a u t h R e q u i r e d ( f u n c ( w h t t p . R e s p o n s e W r i t e r , r * h t t p . R e q u e s t ) { f m t . F p r i n t f ( w , " H i , % v " , r . F o r m V a l u e ( " u s e r " ) ) } , ) A wrapper function. f u n c a u t h R e q u i r e d ( f h t t p . H a n d l e r F u n c ) h t t p . H a n d l e r F u n c { r e t u r n f u n c ( w h t t p . R e s p o n s e W r i t e r , r * h t t p . R e q u e s t ) { i f r . F o r m V a l u e ( " u s e r " ) = = " " { h t t p . E r r o r ( w , " u n k n o w n u s e r " , h t t p . S t a t u s F o r b i d d e n ) r e t u r n } f ( w , r ) } }
  26. Decorators in Go? This is unauthorized: localhost:8080/hi (http://localhost:8080/hi) This is

    authorized: localhost:8080/hi?user=john (http://localhost:8080/hi?user=john) f u n c m a i n ( ) { h t t p . H a n d l e F u n c ( " / h i " , h i H a n d l e r ) h t t p . L i s t e n A n d S e r v e ( " : 8 0 8 0 " , n i l ) } Run
  27. Exercise: errors in HTTP handlers In Go, functions can return

    errors to indicate that something bad happened. The n e t / h t t p package from the standard library defines the type H a n d l e r F u n c . t y p e H a n d l e r F u n c f u n c ( R e s p o n s e W r i t e r , * R e q u e s t ) But it's often useful to unify the error handling into a single function to avoid repetition. t y p e e r r o r H a n d l e r f u n c ( h t t p . R e s p o n s e W r i t e r , * h t t p . R e q u e s t ) e r r o r Write a decorator that given a e r r o r H a n d l e r returns a h t t p . H a n d l e r F u n c . If an error occurs it logs it and returns an http error page.
  28. Exercise: errors in HTTP handlers (continuation) Given the function h

    a n d l e r . f u n c h a n d l e r ( w h t t p . R e s p o n s e W r i t e r , r * h t t p . R e q u e s t ) e r r o r { n a m e : = r . F o r m V a l u e ( " n a m e " ) i f n a m e = = " " { r e t u r n f m t . E r r o r f ( " e m p t y n a m e " ) } f m t . F p r i n t l n ( w , " H i , " , n a m e ) r e t u r n n i l } We want to use it as follows. h t t p . H a n d l e F u n c ( " / h i " , h a n d l e E r r o r ( h a n d l e r ) ) Implement h a n d l e E r r o r using the playground. golang.org/s/go4py-ex3 (http://golang.org/s/go4py-ex3)
  29. Solution: errors in HTTP handlers f u n c h

    a n d l e E r r o r ( f e r r o r H a n d l e r ) h t t p . H a n d l e r F u n c { r e t u r n f u n c ( w h t t p . R e s p o n s e W r i t e r , r * h t t p . R e q u e s t ) { e r r : = f ( w , r ) i f e r r ! = n i l { l o g . P r i n t f ( " % v " , e r r ) h t t p . E r r o r ( w , " O o p s ! " , h t t p . S t a t u s I n t e r n a l S e r v e r E r r o r ) } } } / / F a k e r e q u e s t w i t h o u t ' n a m e ' p a r a m e t e r . r : = & h t t p . R e q u e s t { } w : = n e w D u m m y R e s p ( ) h a n d l e E r r o r ( h a n d l e r ) ( w , r ) f m t . P r i n t l n ( " r e s p a : " , w ) / / F a k e r e q u e s t w i t h ' n a m e ' p a r a m e t e r ' j o h n ' . r . F o r m [ " n a m e " ] = [ ] s t r i n g { " j o h n " } w = n e w D u m m y R e s p ( ) h a n d l e E r r o r ( h a n d l e r ) ( w , r ) f m t . P r i n t l n ( " r e s p b : " , w ) Run
  30. Monkey patching "A monkey patch is a way to extend

    or modify the run-time code of dynamic languages without altering the original source code." - Wikipedia
  31. Monkey patching Also known as "duck punching" ... poor duck.

    Often used for testing purposes. For example, say we want to test this function: d e f s a y _ h i ( u s r ) : i f a u t h ( u s r ) : p r i n t ' H i , % s ' % u s r e l s e : p r i n t ' u n k n o w n u s e r % s ' % u s r Which depends on a function that makes an HTTP request: d e f a u t h ( u s r ) : t r y : r = u r l l i b . u r l o p e n ( a u t h _ u r l + ' / ' + u s r ) r e t u r n r . g e t c o d e ( ) = = 2 0 0 e x c e p t : r e t u r n F a l s e
  32. Monkey patching We can test s a y _ h

    i without making HTTP requests by stubbing out a u t h : d e f s a y h i t e s t ( ) : # T e s t a u t h e n t i c a t e d u s e r g l o b a l s ( ) [ ' a u t h ' ] = l a m b d a x : T r u e s a y _ h i ( ' J o h n ' ) # T e s t u n a u t h e n t i c a t e d u s e r g l o b a l s ( ) [ ' a u t h ' ] = l a m b d a x : F a l s e s a y _ h i ( ' J o h n ' )
  33. Gopher punching! The same effect can be achieved in Go.

    f u n c s a y H i ( u s e r s t r i n g ) { i f ! a u t h ( u s e r ) { f m t . P r i n t f ( " u n k n o w n u s e r % v \ n " , u s e r ) r e t u r n } f m t . P r i n t f ( " H i , % v \ n " , u s e r ) } Which depends on v a r a u t h = f u n c ( u s e r s t r i n g ) b o o l { r e s , e r r : = h t t p . G e t ( a u t h U R L + " / " + u s e r ) r e t u r n e r r = = n i l & & r e s . S t a t u s C o d e = = h t t p . S t a t u s O K }
  34. Gopher punching! Our test code can change the value of

    auth easily. f u n c T e s t S a y H i ( ) { a u t h = f u n c ( s t r i n g ) b o o l { r e t u r n t r u e } s a y H i ( " J o h n " ) a u t h = f u n c ( s t r i n g ) b o o l { r e t u r n f a l s e } s a y H i ( " J o h n " ) } Run
  35. Conclusion Go is a bit like Python simple flexible fun

    but a bit different too fast concurrent statically typed Disclaimer : "No pythons, ducks, monkeys or gophers were harmed while writing this talk"
  36. Try it Next steps golang.org (http://golang.org) Learn Go from your

    browser tour.golang.org (http://tour.golang.org) The community: golang-nuts groups.google.com/d/forum/golang-nuts (https://groups.google.com/d/forum/golang-nuts)