Chris Umbel

First Impressions of Go, Google's New Systems Language

It's funny. These days I hear Google's name mentioned in reference to subjects I never would have imagined three or four years back. Cell phones... Web browsers... Operating Systems... And a systems programming language???

Yes, a systems programming language... By the name of "Go", actually. It boasts garbage collection, enhanced safety and slick concurrency. The idea is that it should perform only slightly slower than C but feel more like python; simple, safe, garbage-collected and plumbing-light.

Considering it was just released to the public a few days ago and I've only been fiddling with it for a few hours now I certainly can claim no authority on the subject. I would, however, like to share some of the little hello-world-style hacks I whipped out while getting myself acquainted with Go.

Hello World

Here's a basic Hello World app.

package main

/* load the "fmt" package. */
import "fmt"

func main() {
    /* write formatted text to console */
     fmt.Println("hello world");
}

Output:

hello world

Hello World 2

Now wrapped in a function. Notice the type follows the identifier in the argument declaration, the opposite of most languages.

package main

import "fmt"

func WriteStuff(message string) {
     fmt.Println(message);
}

func main() {
     WriteStuff("hello world");
}

Concurrency

Concurrency is accomplished by a concept called "goroutines". The implementation is quite elegant. All you have to do is precede your function call with the "go" keyword. Quite nice!

package main

import (
       "fmt";
       "time";
)

func doStuff(message string) {
     for i := 0; i < 10; i++ {
       fmt.Println(message);
       time.Sleep(100);
     }
}

func main() {
     /* the "go" spawns the concurrent goroutine */
     go doStuff("goroutine");

     /* the lack of go runs on the caller */
     doStuff("main");
}

Resulting in output similar to:

goroutine
goroutine
main
main
goroutine
goroutine
main
main
goroutine
goroutine
main
main
goroutine
goroutine
main
main
goroutine
goroutine
main
main

Concurrency 2

Here's basically the same thing, but lambda-like.

package main

import (
       "fmt";
       "time";
)

func main() {
     /* the "go" spawns another thread, lambda style this time */
     go func() {
             for i := 0; i < 10; i++ {
                   fmt.Println("goroutine");
                   time.Sleep(100);
             }
     }(); /* parens indicate we're calling a func */

     for i := 0; i < 10; i++ {
           fmt.Println("main");
           time.Sleep(100);
     }
}

Channels

Communication between threads is accomplished via channels a la Erlang or Stackless Python. More concurrent goodness!

package main

import (
       "fmt";
       "time";
)

func doStuff(id int, c chan string) {
     var s string;

     for i := 0; i < 3; i++ {
        /* receive from the channel */ 
         s = <-c;

         fmt.Printf("%d: %s\n", id, s);
     }
}

func main() {
    /* create a channel with string messages */
     c := make(chan string);

    /* spawn two goroutines that will receive messages */
     go doStuff(1, c);
     go doStuff(2, c);

    /* send messages to the goroutines via our channel */
     c <- "message 1";
     c <- "message 2";
     c <- "message 3";
     c <- "message 4";
     c <- "message 5";
     c <- "message 6";

     time.Sleep(1000);
}

Resulting in output similar to:

1: message 1
1: message 3
2: message 2
1: message 4
2: message 5
2: message 6

Maps

Handy key-value storage is available through maps.

/* create and initialize a map that contains floats
   and is keyed on strings. */
stocks := map[string] float  {
    "JAVA" : 8.67,
    "MSFT" : 29.62,
    "GOOG" : 572.05
};

fmt.Printf("Google is %f\n", stocks["GOOG"]);

/* add a pair to a map */
stocks["ORCL"] = 22.31;

fmt.Printf("Oracle is %f\n", stocks["ORCL"]);

Conclusion

Well, that's the first few hours of hacking around. Obviously this just scratches the surface. I'm looking forward to seeing what people actually produce with Go.

It's interesting, though. We've been so wrapped up in abstracting everything away into runtimes that we may have ignored the possibility of making native/systems languages more productive. Perhaps if it catches on Go will change that.

With its ease of use, memory safety, and simplified concurrency I certainly think it has a shot of improving our lower-level lives.

Sat Nov 14 2009 23:11:00 GMT+0000 (UTC)

Follow Chris
RSS Feed
Twitter
Facebook
CodePlex
github
LinkedIn
Google