SlideShare a Scribd company logo
Ro u
                                            gh
                                       Cut
                                           !

Go
it’s not just for Google


Eleanor McHugh


http://slides.games-with-brains.net/
compiled
garbage collected
imperative
package main

import “fmt”

const HELLO string = “hello”
var WORLD string = “world”

func main() {
	   fmt.Println(HELLO, WORLD)
}
strongly typed
boolean, numeric, array
 value
                    structure, interface


reference   pointer, slice, string, map, channel


function        function, method, closure
underlying               method
  type                    set
             expressed
                type
underlying               method
  type                    set
             expressed
                type




             embedded
               types
package Integer

type Int int

func (i *Int) Add(x int) {
	   *i += Int(x)
}
type Buffer []Int

func (b Buffer) Swap(i, j int) {
	   b[i], b[j] = b[j], b[i]
}

func (b Buffer) Clone() Buffer {
	   s := make(Buffer, len(b))
	   copy(s, b)
	   return s
}

func (b Buffer) Move(i, n int) {
	   if n > len(b) - i {
	   	     n = len(b) - i
	   }
	   segment_to_move := b[:i].Clone()
	   copy(b, b[i:i + n])
	   copy(b[n:i + n], segment_to_move)
}
package main

import “fmt”
import "Integer"

func main() {
	   i := Integer.Buffer{0, 1, 2, 3, 4, 5}   produces:
	   b := i.Clone()                             b[0:2] = [6 4]
	   b.Swap(1, 2)
	   b.Move(3, 2)
	   b[0].Add(3)

   fmt.Printf(“b[0:2] = %vn”, b[0:2])
}
testable
func (b Buffer) Eq(o Buffer) (r bool) {
	   if len(b) == len(o) {
	   	     for i := len(b) - 1; i > 0; i-- {
	   	     	     if b[i] != o[i] {
	   	     	     	      return
	   	     	     }
	   	     }
	   	     r = true
	   }
	   return
}
func TestSwap(t *testing.T) {
	   i := Buffer{0, 1, 2, 3, 4, 5}
	   b := i.Clone()
	   b.Swap(1, 2)
	   if !b[1:3].Eq(Buffer{2, 1}) {
	   	     t.Fatalf("b = %v", b)
	   }
}
package Vector
import . "Integer"

type Vector struct {
	   Buffer
}

func (v *Vector) Clone() *Vector {
	   return &Vector{v.Buffer.Clone()}
}

func (v *Vector) Slice(i, j int) Buffer {
	   return v.Buffer[i:j]
}
package Vector
import "testing"

func TestVectorSwap(t *testing.T) {
	   i := Vector{Buffer{0, 1, 2, 3, 4, 5}}
	   v := i.Clone()
	   v.Swap(1, 2)
	   r := Vector{Buffer{0, 2, 1, 3, 4, 5}}
	   switch {
	   case !v.Eq(r.Buffer):	 	      fallthrough
	   case !v.Buffer.Eq(r.Buffer):	 t.Fatalf("b[0:5] = %v", v)
	   }
}
include $(GOROOT)/src/Make.inc

TARG=integer

GOFILES=
	  integer.go
	  vector.go

include $(GOROOT)/src/Make.pkg
func BenchmarkVectorClone6(b *testing.B) {
	   v := Vector{Buffer{0, 1, 2, 3, 4, 5}}
	   for i := 0; i < b.N; i++ {
	   	     _ = v.Clone()
	   }
}

func BenchmarkVectorSwap(b *testing.B) {
	   b.StopTimer()
	   v := Vector{Buffer{0, 1, 2, 3, 4, 5}}
	   b.StartTimer()
	   for i := 0; i < b.N; i++ {
	   	     v.Swap(1, 2)
	   }
}
$ gotest -bench="Benchmark"
rm -f _test/scripts.a
6g -o _gotest_.6 integer.go vector.go nominal_typing_test.go
embedded_typing_benchmark_test.go embedded_typing_test.go
rm -f _test/scripts.a
gopack grc _test/scripts.a _gotest_.6
PASS
integer.BenchmarkVectorSwap	200000000	            8 ns/op
integer.BenchmarkVectorClone6	 10000000	             300 ns/op
dynamic
type Adder interface {
	   Add(j int)
	   Subtract(j int)
	   Result() interface{}
	   Reset()
}
type IAdder int

func (i IAdder) Add(j int) {
	   i[0] += i[j]
}

func (i IAdder) Subtract(j int) {
	   i[0] -= i[j]
}

func (i IAdder) Result() interface{} {
	   return i[0]
}

func (i IAdder) Reset() {
	   i[0] = *new(int)
}
type FAdder []float32

func (f FAdder) Add(j int) {
	   f[0] += f[j]
}

func (f FAdder) Subtract(j int) {
	   f[0] -= f[j]
}

func (f FAdder) Result() interface{} {
	   return f[0]
}
func TestAdder(t *testing.T) {
	   var a	 Adder

	   a = IAdder{0, 1, 2}
	   a.Add(1)
	   if i.Result().(int) != 1 {
	   	     t.Fatalf("IAdder::Add(1) %v != %v", a.Result(), 1)
	   }
	   a.Subtract(2)
	   if a.Result().(int) != -1 {
	   	     t.Fatalf("IAdder::Subtract(2) %v != %v", a.Result()), -1
	   }

	   a = FAdder{0.0, 1.0, 2.0}
	   a.Add(1)
	   if a.Result().(float32) != 1.0 {
	   	     t.Fatalf("FAdder::Add(1) %v != %v", a.Result(), 1.0)
	   }
}
reflected
package generalise

import "reflect"

func Allocate(i interface{}, limit... int) (n interface{}) {
	   switch v := reflect.ValueOf(i); v.Kind() {
	   case reflect.Slice:		       l := v.Cap()
	   	    	    	     	   	      if len(limit) > 0 {
	   	    	    	     	   	      	     l = limit[0]
	   	    	    	     	   	      }
	   	    	    	     	   	      n = reflect.MakeSlice(v.Type(), l, l).Interface()

	    case reflect.Map:		       n = reflect.MakeMap(v.Type()).Interface()
	    }
	    return
}
package generalise

import . "reflect"

func Allocate(i interface{}, limit... int) (n interface{}) {
	   switch v := ValueOf(i); v.Kind() {
	   case Slice:	 	      l := v.Cap()
	   	    	    	     	   if len(limit) > 0 {
	   	    	    	     	   	      l = limit[0]
	   	    	    	     	   }
	   	    	    	     	   n = MakeSlice(v.Type(), l, l).Interface()

	   case Map:	 	        n = MakeMap(v.Type()).Interface()
	   }
	   return
}
func throwsPanic(f func()) (b bool) {
	   defer func() {
	   	    if x := recover(); x != nil {
	   	    	     b = true
	   	    }
	   }()
	   f()
	   return
}
func TestAllocate(t *testing.T) {
	   var s2 []int

	   s1 := []int{0, 1, 2}
	   m := map[int] int{1: 1, 2: 2, 3: 3}
	   switch {
	   case throwsPanic(func() { s2 = Allocate(s1, 1).([]int) }):
	   	    t.Fatal("Unable to allocate new slice")

	   case len(s2) != 1 || cap(s2) != 1:
	   	   t.Fatal("New slice should be %v not %v", make([]int, 0, 1), s2)

	   case throwsPanic(func() { Allocate(m) }):
	   	   t.Fatal("Unable to allocate new map")
	   }
}
func Duplicate(i interface{}) (clone interface{}) {
	   if clone = Allocate(i); clone != nil {
	   	     switch clone := ValueOf(clone); clone.Kind() {
	   	     case Slice:	 	      	   Copy(clone, ValueOf(i))

	   	    case Map:	    	    	    m := ValueOf(i)
	   	    	   	  	      	    	    for _, k := range m.Keys() {
	   	    	   	  	      	    	    	    clone.SetMapIndex(k, m.MapIndex(k))
	   	    	   	  	      	    	    }
	   	    }
	   }
	   return
}
func TestDuplicateSlice(t *testing.T) {
	   s1 := []int{0, 1, 2}
	   var s2 []int

	   if throwsPanic(func() { s2 = Duplicate(s1).([]int) }) {
	   	     t.Fatalf("Unable to duplicate slice %vn", s1)
	   }
	   switch {
	   case len(s1) != len(s2):	 	  fallthrough
	   case cap(s1) != cap(s2):	 fallthrough
	   case s1[0] != s2[0]:	 	      fallthrough
	   case s1[1] != s2[1]:	 	      fallthrough
	   case s1[2] != s2[2]:	 	      fallthrough
	   	     t.Fatalf("Duplicating %v produced %v", s1, s2)
	   }
}
func TestDuplicateMap(t *testing.T) {
	   m1 := map[int]int{1: 1, 2: 2, 3: 3}
	   var m2 map[int]int

	   if throwsPanic(func() { m2 = Duplicate(m1).(map[int]int) }) {
	   	     t.Fatalf("Unable to duplicate map %vn", m1)
	   }

	   switch {
	   case len(m1) != len(m2):	 fallthrough
	   case m1[1] != m2[1]:	 	    fallthrough
	   case m1[2] != m2[2]:	 	    fallthrough
	   case m1[3] != m2[3]:	 	    fallthrough
	   	   t.Fatalf("Duplicating %v produced %v", m1, m2)
	   }
}
low-level
package raw

import . "reflect"
import "unsafe"

var _BYTE_SLICE Type = Typeof([]byte(nil))

type MemoryBlock interface {
	   ByteSlice() []byte
}

func valueHeader(v reflect.Value) (Header *reflect.SliceHeader) {
	   if v.IsValid() {
	   	      s := int(v.Type().Size())
	   	      header = &reflect.SliceHeader{ v.UnsafeAddr(), s, s }
	   }
	   return
}
func SliceHeader(i interface{}) (Header *SliceHeader, Size, Align int) {
	   switch value := Indirect(ValueOf(i)); value.Kind() {
	   case Slice:	 	     Header = (*SliceHeader)(unsafe.Pointer(value.UnsafeAddr()))
	   	    	   	    	    t := value.Type().Elem()
	   	    	   	    	    Size = int(t.Size())
	   	    	   	    	    Align = t.Align()
	   case Interface:	 Header, Size, Align = SliceHeader(value.Elem())
	   }
	   return
}

func Scale(oldHeader *SliceHeader, oldESize, newESize int) (h *SliceHeader) {
	   if oldHeader != nil {
	   	     s := float64(oldESize) / float64(newESize)
	   	     h = &SliceHeader{ Data: oldHeader.Data }
	   	     h.Len = int(float64(oldHeader.Len) * s)
	   	     h.Cap = int(float64(oldHeader.Cap) * s)
	   }
	   return
}
func ByteSlice(i interface{}) []byte {
	   switch i := i.(type) {
	   case []byte:	 	      	   	     return i
	   case MemoryBlock:	 	           return i.ByteSlice()
	   }

	   var header *SliceHeader
	   switch v := ValueOf(i); value.Kind() {
	   case Interface, Ptr:	 header = valueHeader(v.Elem())

	   case Slice:	 	      	    h, s, _ := SliceHeader(i)
	   	   	    	   	      	    header = Scale(h, s, 1)

	   case String:	 	     	    s := v.Get()
	   	   	    	    	     	    h := *(*StringHeader)(unsafe.Pointer(&s))
	   	   	    	    	     	    header = &SliceHeader{ h.Data, h.Len, h.Len }

	   default:	 	  	   	   header = valueHeader(v)
	   }
	   return unsafe.Unreflect(_BYTE_SLICE, unsafe.Pointer(header)).([]byte)
}
concurrent
package main
import "fmt"

func main() {
	   var c chan int
	   c = make(chan int)
	   limit := 16
	   go func() {
	   	     for i := limit; i > 0; i-- {
                                         produces:
	   	     	     fmt.Print(<-c)
                                            0110011101011010
	   	     }
	   }()
	   for i := limit; i > 0; i-- {
	   	     select {
	   	     case c <- 0:
	   	     case c <- 1:
	   	     }
	   }
}
func main() {
	   var c chan int
	   c = make(chan int, 16)
	   go func() {
	   	     for i := 16; i > 0; i-- {
	   	     	     fmt.Print(<-c)
	   	     }
	   }()                               produces:
	   go func() {                          0110011101011010
	   	     select {
	   	     case c <- 0:
	   	     case c <- 1:
	   	     }
	   }()
	   for {}
}
package generalise

type SignalSource func(status chan bool)

func Wait(s SignalSource) {
	   done := make(chan bool)
	   defer close(done)
	   go s(done)
	   <-done
}

func WaitAll(count int, s SignalSource) {
	   done := make(chan bool)
	   defer close(done)
	   go s(done)
	   for i := 0; i < count; i++ {
	   	     <- done
	   }
}
type Iteration func(k, x interface{}) bool

func (i Iteration) apply(k, v interface{}, c chan bool) {
	   go func() {
	   	      c <-i(k, v)
	   }()
}

func (f Iteration) Each(c interface{}) {
	   switch c := ValueOf(c); c.Kind() {
	   case Slice:	 	       WaitAll(c.Len(), SignalSource(func(done chan bool) {
	   	      	    	   	    	    for i := 0; i < c.Len(); i++ {
	   	      	    	   	    	    	     f.apply(i, c.Elem(i).Interface(), done) }}))

	   case Map:	 	        WaitAll(c.Len(), SignalSource(func(done chan bool) {
	   	   	  	   	        	   for _, k := range c.Keys() {
	   	   	  	   	        	   	     f.apply(k, c.Elem(k).Interface(), done) }}))
	   }
}
type Results chan interface{}

type Combination func(x, y interface{}) interface{}

func (f Combination) Reduce(c, s interface{}) (r Results) {
	   r = make(Results)
	   go func() {
	   	    Iteration(func(k, x interface{}) (ok bool) {
	   	    	    s = f(s, x)
	   	    	    return true
	   	    }).Each(c)
	   	    r <- s
	   }()
	   return
}
type Transformation func(x interface{}) interface{}

func (t Transformation) Transform(x interface{}) Value {
	   return ValueOf(t(x))
}

func (t Transformation) Map(c interface{}) (r interface{}) {
	   r = Allocate(c)
	   if i := MapIterator(r); i != nil {
	   	      i.Each(c)
	   }
	   return
}
func MapIterator(c interface{}) (i Iteration) {
	   switch n := ValueOf(c); n.Kind() {
	   case Slice:	 	     i = Iteration(func(k, x interface{}) bool {
	   	   	    	    	    	     n.Elem(k.(int)).SetValue(t.GetValue(x))
	   	   	    	    	    	     return true
	   	   	    	    	    })

	   case Map:	     	    i = Iteration(func(k, x interface{}) bool {
	   	    	 	       	    	     n.SetMapIndex(ValueOf(k), t.GetValue(x))
	   	    	 	       	    	     return true
	   	    	 	       	    })
	   }
	   return
}
func main() {
	   s := []int{0, 1, 2, 3, 4, 5}
	   d := Transformation(func(x interface{}) interface{} {
	   	    return x.(int) * 2 }
	   ).Map(s)
	   sum := Combination(func(x, y interface{}) interface{} {
	   	    return x.(int) + y.(int)
	   })
	   fmt.Printf("s = %v, sum = %vn", s, (<- sum.Reduce(s, 0)).(int))
	   fmt.Printf("d = %v, sum = %vn", d, (<- sum.Reduce(d, 0)).(int))
}


                                               produces:
                                                  s = [0 1 2 3 4 5], sum = 15
                                                  d = [0 2 4 6 8 10], sum = 30
extensible
include $(GOROOT)/src/Make.inc

TARG=sqlite3

CGOFILES=
	  sqlite3.go
	  database.go

ifeq ($(GOOS),darwin)
CGO_LDFLAGS=/usr/lib/libsqlite3.0.dylib
else
CGO_LDFLAGS=-lsqlite3
endif

include $(GOROOT)/src/Make.pkg
package sqlite3

// #include <sqlite3.h>
import "C"
import "fmt"
import "os"

type Database struct {
	   handle	 	    	     	   *C.sqlite3
	   Filename	    	     	   string
	   Flags	 	     	     	   C.int
}

func (db *Database) Error() os.Error {
	   return Errno(C.sqlite3_errcode(db.handle))
}
const(
	   OK	 	 	   = Errno(iota)
	   ERROR
	   CANTOPEN	 = Errno(14)
)

var errText = map[Errno]string {
	    ERROR: 	    	    "SQL error or missing database",
	    CANTOPEN:		      "Unable to open the database file",
}

type Errno int

func (e Errno) String() (err string) {
	   if err = errText[e]; err == "" {
	   	     err = fmt.Sprintf("errno %v", int(e))
	   }
	   return
}
func (db *Database) Open(flags... int) (e os.Error) {
	   db.Flags = 0
	   for _, v := range flags {
	   	     db.Flags = db.Flags | C.int(v)
	   }
	   f := C.CString(db.Filename)
	   if err := Errno(C.sqlite3_open_v2(f, &db.handle, db.Flags, nil)); err != OK {
	   	     e = err
	   } else if db.handle == nil {
	   	     e = CANTOPEN
	   }
	   return
}

func (db *Database) Close() {
	   C.sqlite3_close(db.handle)
	   db.handle = nil
}
func Open(filename string, flags... int) (db *Database, e os.Error) {
	   defer func() {
	   	     if x := recover(); x != nil {
	   	     	     db.Close()
	   	     	     db = nil
	   	     	     e = ERROR
	   	     }
	   }()
	   db = &Database{ Filename: filename }
	   if len(flags) == 0 {
	   	     e = db.Open(	  	     C.SQLITE_OPEN_FULLMUTEX,
	   	     	     	    	   	     C.SQLITE_OPEN_READWRITE,
	   	     	     	    	   	     C.SQLITE_OPEN_CREATE )
	   } else {
	   	     e = db.Open(flags...)
	   }
	   return
}
fun!
finding out more

http://golang.org/
twitter://#golightly
http://github.com/feyeleanor/
wikipedia or google

More Related Content

What's hot

C++ TUTORIAL 3
C++ TUTORIAL 3C++ TUTORIAL 3
C++ TUTORIAL 3
Farhan Ab Rahman
 
C++ TUTORIAL 4
C++ TUTORIAL 4C++ TUTORIAL 4
C++ TUTORIAL 4
Farhan Ab Rahman
 
Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoF
Timur Safin
 
C++ TUTORIAL 1
C++ TUTORIAL 1C++ TUTORIAL 1
C++ TUTORIAL 1
Farhan Ab Rahman
 
Data Structure - 2nd Study
Data Structure - 2nd StudyData Structure - 2nd Study
Data Structure - 2nd Study
Chris Ohk
 
Travel management
Travel managementTravel management
Travel management1Parimal2
 
Daa practicals
Daa practicalsDaa practicals
Daa practicals
Rekha Yadav
 
Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functions
Franco Lombardo
 
C++ Programming - 1st Study
C++ Programming - 1st StudyC++ Programming - 1st Study
C++ Programming - 1st Study
Chris Ohk
 
Hello Swift 3/5 - Function
Hello Swift 3/5 - FunctionHello Swift 3/5 - Function
Hello Swift 3/5 - Function
Cody Yun
 
PyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutinePyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into Coroutine
Daehee Kim
 
Double linked list
Double linked listDouble linked list
Double linked list
Sayantan Sur
 
Svitla talks 2021_03_25
Svitla talks 2021_03_25Svitla talks 2021_03_25
Svitla talks 2021_03_25
Ruslan Shevchenko
 
Blocks+gcd入門
Blocks+gcd入門Blocks+gcd入門
Blocks+gcd入門
領一 和泉田
 
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Ruslan Shevchenko
 
BCSL 058 solved assignment
BCSL 058 solved assignmentBCSL 058 solved assignment
Double linked list
Double linked listDouble linked list
Double linked list
raviahuja11
 
6. Generics. Collections. Streams
6. Generics. Collections. Streams6. Generics. Collections. Streams
6. Generics. Collections. Streams
DEVTYPE
 

What's hot (20)

C++ TUTORIAL 3
C++ TUTORIAL 3C++ TUTORIAL 3
C++ TUTORIAL 3
 
C++ TUTORIAL 4
C++ TUTORIAL 4C++ TUTORIAL 4
C++ TUTORIAL 4
 
Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoF
 
C++ TUTORIAL 1
C++ TUTORIAL 1C++ TUTORIAL 1
C++ TUTORIAL 1
 
Data Structure - 2nd Study
Data Structure - 2nd StudyData Structure - 2nd Study
Data Structure - 2nd Study
 
Travel management
Travel managementTravel management
Travel management
 
Daa practicals
Daa practicalsDaa practicals
Daa practicals
 
Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functions
 
C++ Programming - 1st Study
C++ Programming - 1st StudyC++ Programming - 1st Study
C++ Programming - 1st Study
 
Hello Swift 3/5 - Function
Hello Swift 3/5 - FunctionHello Swift 3/5 - Function
Hello Swift 3/5 - Function
 
C++ programs
C++ programsC++ programs
C++ programs
 
PyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutinePyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into Coroutine
 
Double linked list
Double linked listDouble linked list
Double linked list
 
Svitla talks 2021_03_25
Svitla talks 2021_03_25Svitla talks 2021_03_25
Svitla talks 2021_03_25
 
Blocks+gcd入門
Blocks+gcd入門Blocks+gcd入門
Blocks+gcd入門
 
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
 
BCSL 058 solved assignment
BCSL 058 solved assignmentBCSL 058 solved assignment
BCSL 058 solved assignment
 
Struct examples
Struct examplesStruct examples
Struct examples
 
Double linked list
Double linked listDouble linked list
Double linked list
 
6. Generics. Collections. Streams
6. Generics. Collections. Streams6. Generics. Collections. Streams
6. Generics. Collections. Streams
 

Similar to Go: It's Not Just For Google

Go a crash course
Go   a crash courseGo   a crash course
Go a crash course
Eleanor McHugh
 
GoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoGoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google Go
Eleanor McHugh
 
Monadologie
MonadologieMonadologie
Monadologie
league
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
Tor Ivry
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
진성 오
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
Adam Dudczak
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and Go
Eleanor McHugh
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby Hackers
Eleanor McHugh
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
Fabio Collini
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
Anton Arhipov
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
league
 
3 kotlin vs. java- what kotlin has that java does not
3  kotlin vs. java- what kotlin has that java does not3  kotlin vs. java- what kotlin has that java does not
3 kotlin vs. java- what kotlin has that java does not
Sergey Bandysik
 
JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyYasuharu Nakano
 
L25-L26-Parameter passing techniques.pptx
L25-L26-Parameter passing techniques.pptxL25-L26-Parameter passing techniques.pptx
L25-L26-Parameter passing techniques.pptx
happycocoman
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
Guy Komari
 
Concurrent Application Development using Scala
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using Scala
Siarhiej Siemianchuk
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
Christian Baranowski
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)
Ishin Vin
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
Hang Zhao
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語
ikdysfm
 

Similar to Go: It's Not Just For Google (20)

Go a crash course
Go   a crash courseGo   a crash course
Go a crash course
 
GoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoGoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google Go
 
Monadologie
MonadologieMonadologie
Monadologie
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and Go
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby Hackers
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
3 kotlin vs. java- what kotlin has that java does not
3  kotlin vs. java- what kotlin has that java does not3  kotlin vs. java- what kotlin has that java does not
3 kotlin vs. java- what kotlin has that java does not
 
JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovy
 
L25-L26-Parameter passing techniques.pptx
L25-L26-Parameter passing techniques.pptxL25-L26-Parameter passing techniques.pptx
L25-L26-Parameter passing techniques.pptx
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
 
Concurrent Application Development using Scala
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using Scala
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語
 

More from Eleanor McHugh

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
Eleanor McHugh
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
Eleanor McHugh
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
Eleanor McHugh
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
Eleanor McHugh
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
Eleanor McHugh
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
Eleanor McHugh
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Eleanor McHugh
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
Eleanor McHugh
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
Eleanor McHugh
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
Eleanor McHugh
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
Eleanor McHugh
 
Hello Go
Hello GoHello Go
Hello Go
Eleanor McHugh
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
Eleanor McHugh
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with Go
Eleanor McHugh
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in go
Eleanor McHugh
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
Eleanor McHugh
 
Implementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CImplementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & C
Eleanor McHugh
 
Implementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & CImplementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & C
Eleanor McHugh
 

More from Eleanor McHugh (20)

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
 
Hello Go
Hello GoHello Go
Hello Go
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with Go
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in go
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
 
Implementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CImplementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & C
 
Implementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & CImplementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & C
 

Recently uploaded

FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 

Go: It's Not Just For Google

  • 1. Ro u gh Cut ! Go it’s not just for Google Eleanor McHugh http://slides.games-with-brains.net/
  • 5. package main import “fmt” const HELLO string = “hello” var WORLD string = “world” func main() { fmt.Println(HELLO, WORLD) }
  • 7. boolean, numeric, array value structure, interface reference pointer, slice, string, map, channel function function, method, closure
  • 8. underlying method type set expressed type
  • 9. underlying method type set expressed type embedded types
  • 10. package Integer type Int int func (i *Int) Add(x int) { *i += Int(x) }
  • 11. type Buffer []Int func (b Buffer) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b Buffer) Clone() Buffer { s := make(Buffer, len(b)) copy(s, b) return s } func (b Buffer) Move(i, n int) { if n > len(b) - i { n = len(b) - i } segment_to_move := b[:i].Clone() copy(b, b[i:i + n]) copy(b[n:i + n], segment_to_move) }
  • 12. package main import “fmt” import "Integer" func main() { i := Integer.Buffer{0, 1, 2, 3, 4, 5} produces: b := i.Clone() b[0:2] = [6 4] b.Swap(1, 2) b.Move(3, 2) b[0].Add(3) fmt.Printf(“b[0:2] = %vn”, b[0:2]) }
  • 14. func (b Buffer) Eq(o Buffer) (r bool) { if len(b) == len(o) { for i := len(b) - 1; i > 0; i-- { if b[i] != o[i] { return } } r = true } return }
  • 15. func TestSwap(t *testing.T) { i := Buffer{0, 1, 2, 3, 4, 5} b := i.Clone() b.Swap(1, 2) if !b[1:3].Eq(Buffer{2, 1}) { t.Fatalf("b = %v", b) } }
  • 16. package Vector import . "Integer" type Vector struct { Buffer } func (v *Vector) Clone() *Vector { return &Vector{v.Buffer.Clone()} } func (v *Vector) Slice(i, j int) Buffer { return v.Buffer[i:j] }
  • 17. package Vector import "testing" func TestVectorSwap(t *testing.T) { i := Vector{Buffer{0, 1, 2, 3, 4, 5}} v := i.Clone() v.Swap(1, 2) r := Vector{Buffer{0, 2, 1, 3, 4, 5}} switch { case !v.Eq(r.Buffer): fallthrough case !v.Buffer.Eq(r.Buffer): t.Fatalf("b[0:5] = %v", v) } }
  • 18. include $(GOROOT)/src/Make.inc TARG=integer GOFILES= integer.go vector.go include $(GOROOT)/src/Make.pkg
  • 19. func BenchmarkVectorClone6(b *testing.B) { v := Vector{Buffer{0, 1, 2, 3, 4, 5}} for i := 0; i < b.N; i++ { _ = v.Clone() } } func BenchmarkVectorSwap(b *testing.B) { b.StopTimer() v := Vector{Buffer{0, 1, 2, 3, 4, 5}} b.StartTimer() for i := 0; i < b.N; i++ { v.Swap(1, 2) } }
  • 20. $ gotest -bench="Benchmark" rm -f _test/scripts.a 6g -o _gotest_.6 integer.go vector.go nominal_typing_test.go embedded_typing_benchmark_test.go embedded_typing_test.go rm -f _test/scripts.a gopack grc _test/scripts.a _gotest_.6 PASS integer.BenchmarkVectorSwap 200000000 8 ns/op integer.BenchmarkVectorClone6 10000000 300 ns/op
  • 22. type Adder interface { Add(j int) Subtract(j int) Result() interface{} Reset() }
  • 23. type IAdder int func (i IAdder) Add(j int) { i[0] += i[j] } func (i IAdder) Subtract(j int) { i[0] -= i[j] } func (i IAdder) Result() interface{} { return i[0] } func (i IAdder) Reset() { i[0] = *new(int) }
  • 24. type FAdder []float32 func (f FAdder) Add(j int) { f[0] += f[j] } func (f FAdder) Subtract(j int) { f[0] -= f[j] } func (f FAdder) Result() interface{} { return f[0] }
  • 25. func TestAdder(t *testing.T) { var a Adder a = IAdder{0, 1, 2} a.Add(1) if i.Result().(int) != 1 { t.Fatalf("IAdder::Add(1) %v != %v", a.Result(), 1) } a.Subtract(2) if a.Result().(int) != -1 { t.Fatalf("IAdder::Subtract(2) %v != %v", a.Result()), -1 } a = FAdder{0.0, 1.0, 2.0} a.Add(1) if a.Result().(float32) != 1.0 { t.Fatalf("FAdder::Add(1) %v != %v", a.Result(), 1.0) } }
  • 27. package generalise import "reflect" func Allocate(i interface{}, limit... int) (n interface{}) { switch v := reflect.ValueOf(i); v.Kind() { case reflect.Slice: l := v.Cap() if len(limit) > 0 { l = limit[0] } n = reflect.MakeSlice(v.Type(), l, l).Interface() case reflect.Map: n = reflect.MakeMap(v.Type()).Interface() } return }
  • 28. package generalise import . "reflect" func Allocate(i interface{}, limit... int) (n interface{}) { switch v := ValueOf(i); v.Kind() { case Slice: l := v.Cap() if len(limit) > 0 { l = limit[0] } n = MakeSlice(v.Type(), l, l).Interface() case Map: n = MakeMap(v.Type()).Interface() } return }
  • 29. func throwsPanic(f func()) (b bool) { defer func() { if x := recover(); x != nil { b = true } }() f() return }
  • 30. func TestAllocate(t *testing.T) { var s2 []int s1 := []int{0, 1, 2} m := map[int] int{1: 1, 2: 2, 3: 3} switch { case throwsPanic(func() { s2 = Allocate(s1, 1).([]int) }): t.Fatal("Unable to allocate new slice") case len(s2) != 1 || cap(s2) != 1: t.Fatal("New slice should be %v not %v", make([]int, 0, 1), s2) case throwsPanic(func() { Allocate(m) }): t.Fatal("Unable to allocate new map") } }
  • 31. func Duplicate(i interface{}) (clone interface{}) { if clone = Allocate(i); clone != nil { switch clone := ValueOf(clone); clone.Kind() { case Slice: Copy(clone, ValueOf(i)) case Map: m := ValueOf(i) for _, k := range m.Keys() { clone.SetMapIndex(k, m.MapIndex(k)) } } } return }
  • 32. func TestDuplicateSlice(t *testing.T) { s1 := []int{0, 1, 2} var s2 []int if throwsPanic(func() { s2 = Duplicate(s1).([]int) }) { t.Fatalf("Unable to duplicate slice %vn", s1) } switch { case len(s1) != len(s2): fallthrough case cap(s1) != cap(s2): fallthrough case s1[0] != s2[0]: fallthrough case s1[1] != s2[1]: fallthrough case s1[2] != s2[2]: fallthrough t.Fatalf("Duplicating %v produced %v", s1, s2) } }
  • 33. func TestDuplicateMap(t *testing.T) { m1 := map[int]int{1: 1, 2: 2, 3: 3} var m2 map[int]int if throwsPanic(func() { m2 = Duplicate(m1).(map[int]int) }) { t.Fatalf("Unable to duplicate map %vn", m1) } switch { case len(m1) != len(m2): fallthrough case m1[1] != m2[1]: fallthrough case m1[2] != m2[2]: fallthrough case m1[3] != m2[3]: fallthrough t.Fatalf("Duplicating %v produced %v", m1, m2) } }
  • 35. package raw import . "reflect" import "unsafe" var _BYTE_SLICE Type = Typeof([]byte(nil)) type MemoryBlock interface { ByteSlice() []byte } func valueHeader(v reflect.Value) (Header *reflect.SliceHeader) { if v.IsValid() { s := int(v.Type().Size()) header = &reflect.SliceHeader{ v.UnsafeAddr(), s, s } } return }
  • 36. func SliceHeader(i interface{}) (Header *SliceHeader, Size, Align int) { switch value := Indirect(ValueOf(i)); value.Kind() { case Slice: Header = (*SliceHeader)(unsafe.Pointer(value.UnsafeAddr())) t := value.Type().Elem() Size = int(t.Size()) Align = t.Align() case Interface: Header, Size, Align = SliceHeader(value.Elem()) } return } func Scale(oldHeader *SliceHeader, oldESize, newESize int) (h *SliceHeader) { if oldHeader != nil { s := float64(oldESize) / float64(newESize) h = &SliceHeader{ Data: oldHeader.Data } h.Len = int(float64(oldHeader.Len) * s) h.Cap = int(float64(oldHeader.Cap) * s) } return }
  • 37. func ByteSlice(i interface{}) []byte { switch i := i.(type) { case []byte: return i case MemoryBlock: return i.ByteSlice() } var header *SliceHeader switch v := ValueOf(i); value.Kind() { case Interface, Ptr: header = valueHeader(v.Elem()) case Slice: h, s, _ := SliceHeader(i) header = Scale(h, s, 1) case String: s := v.Get() h := *(*StringHeader)(unsafe.Pointer(&s)) header = &SliceHeader{ h.Data, h.Len, h.Len } default: header = valueHeader(v) } return unsafe.Unreflect(_BYTE_SLICE, unsafe.Pointer(header)).([]byte) }
  • 39. package main import "fmt" func main() { var c chan int c = make(chan int) limit := 16 go func() { for i := limit; i > 0; i-- { produces: fmt.Print(<-c) 0110011101011010 } }() for i := limit; i > 0; i-- { select { case c <- 0: case c <- 1: } } }
  • 40. func main() { var c chan int c = make(chan int, 16) go func() { for i := 16; i > 0; i-- { fmt.Print(<-c) } }() produces: go func() { 0110011101011010 select { case c <- 0: case c <- 1: } }() for {} }
  • 41. package generalise type SignalSource func(status chan bool) func Wait(s SignalSource) { done := make(chan bool) defer close(done) go s(done) <-done } func WaitAll(count int, s SignalSource) { done := make(chan bool) defer close(done) go s(done) for i := 0; i < count; i++ { <- done } }
  • 42. type Iteration func(k, x interface{}) bool func (i Iteration) apply(k, v interface{}, c chan bool) { go func() { c <-i(k, v) }() } func (f Iteration) Each(c interface{}) { switch c := ValueOf(c); c.Kind() { case Slice: WaitAll(c.Len(), SignalSource(func(done chan bool) { for i := 0; i < c.Len(); i++ { f.apply(i, c.Elem(i).Interface(), done) }})) case Map: WaitAll(c.Len(), SignalSource(func(done chan bool) { for _, k := range c.Keys() { f.apply(k, c.Elem(k).Interface(), done) }})) } }
  • 43. type Results chan interface{} type Combination func(x, y interface{}) interface{} func (f Combination) Reduce(c, s interface{}) (r Results) { r = make(Results) go func() { Iteration(func(k, x interface{}) (ok bool) { s = f(s, x) return true }).Each(c) r <- s }() return }
  • 44. type Transformation func(x interface{}) interface{} func (t Transformation) Transform(x interface{}) Value { return ValueOf(t(x)) } func (t Transformation) Map(c interface{}) (r interface{}) { r = Allocate(c) if i := MapIterator(r); i != nil { i.Each(c) } return }
  • 45. func MapIterator(c interface{}) (i Iteration) { switch n := ValueOf(c); n.Kind() { case Slice: i = Iteration(func(k, x interface{}) bool { n.Elem(k.(int)).SetValue(t.GetValue(x)) return true }) case Map: i = Iteration(func(k, x interface{}) bool { n.SetMapIndex(ValueOf(k), t.GetValue(x)) return true }) } return }
  • 46. func main() { s := []int{0, 1, 2, 3, 4, 5} d := Transformation(func(x interface{}) interface{} { return x.(int) * 2 } ).Map(s) sum := Combination(func(x, y interface{}) interface{} { return x.(int) + y.(int) }) fmt.Printf("s = %v, sum = %vn", s, (<- sum.Reduce(s, 0)).(int)) fmt.Printf("d = %v, sum = %vn", d, (<- sum.Reduce(d, 0)).(int)) } produces: s = [0 1 2 3 4 5], sum = 15 d = [0 2 4 6 8 10], sum = 30
  • 48. include $(GOROOT)/src/Make.inc TARG=sqlite3 CGOFILES= sqlite3.go database.go ifeq ($(GOOS),darwin) CGO_LDFLAGS=/usr/lib/libsqlite3.0.dylib else CGO_LDFLAGS=-lsqlite3 endif include $(GOROOT)/src/Make.pkg
  • 49. package sqlite3 // #include <sqlite3.h> import "C" import "fmt" import "os" type Database struct { handle *C.sqlite3 Filename string Flags C.int } func (db *Database) Error() os.Error { return Errno(C.sqlite3_errcode(db.handle)) }
  • 50. const( OK = Errno(iota) ERROR CANTOPEN = Errno(14) ) var errText = map[Errno]string { ERROR: "SQL error or missing database", CANTOPEN: "Unable to open the database file", } type Errno int func (e Errno) String() (err string) { if err = errText[e]; err == "" { err = fmt.Sprintf("errno %v", int(e)) } return }
  • 51. func (db *Database) Open(flags... int) (e os.Error) { db.Flags = 0 for _, v := range flags { db.Flags = db.Flags | C.int(v) } f := C.CString(db.Filename) if err := Errno(C.sqlite3_open_v2(f, &db.handle, db.Flags, nil)); err != OK { e = err } else if db.handle == nil { e = CANTOPEN } return } func (db *Database) Close() { C.sqlite3_close(db.handle) db.handle = nil }
  • 52. func Open(filename string, flags... int) (db *Database, e os.Error) { defer func() { if x := recover(); x != nil { db.Close() db = nil e = ERROR } }() db = &Database{ Filename: filename } if len(flags) == 0 { e = db.Open( C.SQLITE_OPEN_FULLMUTEX, C.SQLITE_OPEN_READWRITE, C.SQLITE_OPEN_CREATE ) } else { e = db.Open(flags...) } return }
  • 53. fun!

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n