Ruby is awesome!

t-rex

Ruby Infrastructure

ruby

Golang

gopher

Golang

  • A better C (2 compiler (gc, gcc), one interpreter)
  • Memory management is handled for you, but don’t be wreckless
  • Explicit is better than implicit
  • Rich built-in functionality
  • Fast.. everything (from compilation to execution)
  • Concurrency built-in and made easy
  • Documentation is critical
  • And ... nothing new
gopher

Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++.
Robert C. Pike
Google
Python and Ruby programmers come to Go because they don't have to surrender much expressiveness, but gain performance and get to play with concurrency.
Robert C. Pike
Google

Hello, RubyShift!

Golang

package main

import (
  "fmt"
)

func main() {
  fmt.Println("Привет, RubyShift!")
}
      

Hello, HTTP/1.1 RubyShift!

Golang

package main
import (
  "net/http"
  "fmt"
)

func HelloServer(w http.ResponseWriter, req *http.Request) {
	fmt.Fprint(w, "Привет, RubyShift!")
}

func main() {
	http.HandleFunc("/", HelloServer)
	http.ListenAndServe(":6789", nil)
}
      

A quick introduction

Golang

Packages, imports and exported names

A quick introduction

package main

import (
  "fmt"
  "math/rand"
)

func main() {
  fmt.Println("My favorite number is", rand.Intn(10))
}
      

Basic types

A quick introduction

  • bool
  • string
  • int int8 int16 int32 int64
  • uint uint8 uint16 uint32 uint64 uintptr
  • byte // alias for uint8
  • rune // alias for int32, represents a Unicode code point
  • float32 float64
  • complex64 complex128
  • bool

  package main
  import (
      "fmt"
      "math/cmplx"
  )
  var (
      ToBe   bool       = false
      MaxInt uint64     = 1<<64 - 1
      z      complex128 = cmplx.Sqrt(-5 + 12i)
  )
  func main() {
      const f = "%T(%v)\n"
      fmt.Printf(f, ToBe, ToBe)
      fmt.Printf(f, MaxInt, MaxInt)
      fmt.Printf(f, z, z)
  }

Structs

A quick introduction

package main

import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    fmt.Println(Vertex{1, 2})
}
      

Pointers

A quick introduction

package main
import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    p := Vertex{1, 2}
    q := &p
    q.X = 1e9
    fmt.Println(p)
}
      

Slices

A quick introduction

package main

import "fmt"

func main() {
    p := []int{2, 3, 5, 7, 11, 13}
    fmt.Println("p ==", p)

    for i := 0; i < len(p); i++ {
        fmt.Printf("p[%d] == %d\n",
            i, p[i])
    }
}
      

Maps

A quick introduction

package main
import "fmt"

type Vertex struct {
    Lat, Long float64
}
var m map[string]Vertex

func main() {
    m = make(map[string]Vertex)
    m["Bell Labs"] = Vertex{
        40.68433, -74.39967,
    }
    fmt.Println(m["Bell Labs"])
}
      

Interfaces

A quick introduction

  package main

  import (
      "fmt"
      "math"
  )

  type Abser interface {
      Abs() float64
  }

  func main() {
      var a Abser
      f := MyFloat(-math.Sqrt2)
      v := Vertex{3, 4}

      a = f  // a MyFloat implements Abser
      a = &v // a *Vertex implements Abser
      a = v  // a Vertex, does NOT
      // implement Abser

      fmt.Println(a.Abs())
  }

  type MyFloat float64

  func (f MyFloat) Abs() float64 {
      if f < 0 {
          return float64(-f)
      }
      return float64(f)
  }

  type Vertex struct {
      X, Y float64
  }

  func (v *Vertex) Abs() float64 {
      return math.Sqrt(v.X*v.X + v.Y*v.Y)
  }
        

Errors

A quick introduction

  package main

  import (
      "fmt"
      "time"
  )

  type MyError struct {
      When time.Time
      What string
  }

  func (e *MyError) Error() string {
      return fmt.Sprintf("at %v, %s",
          e.When, e.What)
  }

  func run() error {
      return &MyError{
          time.Now(),
          "it didn't work",
      }
  }

  func main() {
      if err := run(); err != nil {
          fmt.Println(err)
      }
  }
        

Goroutines

A quick introduction

  package main
  import (
      "fmt"
      "time"
  )

  func say(s string) {
      for i := 0; i < 5; i++ {
          time.Sleep(100 * time.Millisecond)
          fmt.Println(s)
      }
  }
  func main() {
      go say("world")
      say("hello")
  }
      

Channels

A quick introduction

  package main

  import "fmt"

  func sum(a []int, c chan int) {
      sum := 0
      for _, v := range a {
          sum += v
      }
      c <- sum // send sum to c
  }

  func main() {
      a := []int{7, 2, 8, -9, 4, 0}

      c := make(chan int)
      go sum(a[:len(a)/2], c)
      go sum(a[len(a)/2:], c)
      x, y := <-c, <-c // receive from c

      fmt.Println(x, y, x+y)
  }
      

Select

A quick introduction

  package main

  import "fmt"

  func fibonacci(c, quit chan int) {
      x, y := 0, 1
      for {
          select {
          case c <- x:
              x, y = y, x+y
          case <-quit:
              fmt.Println("quit")
              return
          }
      }
  }

  func main() {
      c := make(chan int)
      quit := make(chan int)
      go func() {
          for i := 0; i < 10; i++ {
              fmt.Println(<-c)
          }
          quit <- 0
      }()
      fibonacci(c, quit)
  }
      

GO and Web

Golang

HTTP Server

GO and Web

  package main

  import (
    "fmt"
    "net/http"
  )
  type Hello struct{}

  func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello!")
  }

  func main() {
    var h Hello
    http.ListenAndServe("localhost:4000", h)
  }

      

Web frameworks and packages

GO and Web

Practical use of GO

Golang

Good and Bad choices

Practical use of GO

Good choice:

  • Background workers
  • Websocket servers
  • SMTP, POP3 servers
  • REST API backend
  • System daemons (monitoring, etc.)

Bad choice:

  • Low level programming (drivers, etc.)
  • Rich web service
  • Complex business logic with huge amount of external libraries
  • Replace Rails, Ruby, Python, etc.
Benchmarks is bullshit! Benchmarks are mainly used to promote specific products as the "fastest".
Me

Benchmarks

http://www.techempower.com/benchmarks/#section=data-r6

Benchmarks

http://benchmarksgame.alioth.debian.org/u32/performance.php?test=threadring

Conclusion

  • Cool language with cool mascot!
  • Very fast language (faster then Ruby and Python)
  • But it is not intended as a substitute for Ruby or Python
  • Poor infrastructure
  • Don't believe in my words - just try it!
gopher

<Thank You!>

My contact information.