So I've been checking out Google's new "Go" language. There's an interesting example at the Go tutorial. Specifically, the following code is a simple very of "echo".
package main import ( "os"; "flag"; // command line option parser ) var omitNewLine = flag.Bool("n", false, "don't print final newline"); const ( Space = " "; Newline = "\n"; ) func main() { flag.Parse(); s := ""; for i := 0; i < flag.NArg(); i++ { if i > 0 { s += Space; } s += flag.Arg(i); } if !*omitNewLine { s += Newline } os.Stdout.WriteString(s); }
Basically, it checks your leading options for the presence of an "-n" switch and, if present, does not emit a trailing new line. Other than that, it prints the arguments to the program, separated by spaces. It might seem rather verbose, but you have to remember that Google envisions this as a systems language. Note that you don't have to reallocate anything for the "s" variable as Go handles that for you. Trying to dynamically resize strings in C leads to fun bugs, but you don't have to do that here. Go takes care of memory management for you.
You might have noticed the var s string = ""; line. Go doesn't support type inference, but it has a simplified version for variable declaration. In the above, you could omit the "string" keyword, or just use the ":=" operator and declare and assign in one fell swoop:
var s string = ""; var s = ""; // go knows you wanted a string s := ""; // same thing
Unlike some dynamic languages, declaration and assignment are clearly separate, making it easy to put proper scoping semantics into the language (though I haven't really checked out how they handle scoping yet) and avoiding silly issues where you think you're assigning to a variable but you've mistyped the name and you're also declaring it.
I'm also intrigued by their lack of a type hierarchy in favor of interfaces. In short, you don't get inheritance. Going with interfaces seems a poor choice because you still have the reimplementation problem, but I'm curious to see what will become of this. Dr. Michele Simionato has an interesting blog entry discussing his initial surprise at being introduced to objects. His background is mathematical in nature and he just didn't understand the need for type hierarchies.
Another interesting bit about Go is that you can't do pointer math wrong. That's because they have pointers, but no pointer math. Kind of like references in Perl, eh? Seems an obvious step.
I'll play more with Go as I have time, but it's beginning to look like there are some interesting ideas for a systems language. I'm curious to know if the lack of full-blown type inference was a deliberate design decision to ensure that the developer can see what's happening at every step of the way, except for the common cases where it's frickin' obvious (such as assigning an int to a variable).