My thoughts on Google Go
bentilly.blogspot.com
bentilly.blogspot.com
1. Terrible name
2. Theres no reason to keep to C-style syntax
3. go <function> is a nice feature
4. Control structures add nothing new and just seem generally underwhelming to me
5. The built-in data types are an improvement over a lot of languages, but are underwhelming when compared to something like Clojure, Haskell, OCaml or Factor
6. Channels are a great way of dealing with mutable data in a concurrent environment, but I'm not convinced they're enough
7. Slices and pointers without arithmetic are a good idea
8. The interface system seems like an interesting idea
9. I'm not sure I understand how this is to be a "systems language", especially when they say that its impossible to do manual memory management
10. Lack of things I like: lisp-like macros, closures, pattern matching, parametric types, dataflow constructs, iterators, list comprehension..
Though I personally don't like the syntax very much, it is certainly familiar and easy enough to pick up, so I imagine this will be useful to a lot of people. I think Go is an interesting experiment which will, hopefully, lead to some more powerful and interesting languages, but I cant see myself ever using Go itself.
Its nice to see a C-like language take concurrency more seriously, but after having used Clojure a lot over the past month or two, it just doesn't really seem so concurrency oriented to me.
Channels are a fantastic for concurrent environments. I took a distributed operating systems course during my graduate work, and we used Inferno as the environment and Limbo as our programming language of choice (you'll notice that one of the developers helped write Limbo). Channels made communicating between threads extremely easy as they could by typed to anything you wanted (primitives, ADT's, etc). Will they be enough? I'm not sure, but my experience tells me that they probably will be.
However, there are some problems which are not easily modeled in this way. Some people claim that for some problems, this method isn't suitable at all (I'm more inclined to say that its simply more difficult or messy, but IMHO thats reason enough). Sometimes shared memory based concurrency is needed for performance. Whatever the reason, I'm not convinced that channels are enough.
This is one reason why I like Clojure's concurrency support: clojure's agents are similar to go's channels, but clojure also supports shared state, using software transactional memory to ease the locking/synchronization pain. Also, since clojure code is, by default, functional, operating on immutable data-structures, a lot of logic is inherently thread-safe at no effort to the programmer. Yet in some cases even that isn't desirable. So it lets you code however you need, and since Clojure is hosted on the JVM, you can revert to using Javas monitor-based concurrency model when it makes sense.
I don't think Clojure solves the worlds concurrency issues, but I'd argue its a lot closer to doing so than Go, even if its just because it gives you the choice to pick the model that suits your particular problem the best.
I don't actually mean to be advertising Clojure, its simply the most concurrency-oriented language I've been spending a lot of time using lately, so its easier for me to compare and contrast Go with it.
Having said that, I'd probably prefer people write code in Go over C hacks.
[1] C++ was my language of choice for a few years, so I do, at least partially, compare a language to C++ when I learn a new one and not only to <latest cool language>, though I admit I do that too.
Given that it has garbage collection, arrays/slices, and it disallows pointer arithmetic, it seems it would suffice to use references everywhere.
I thought maybe it was for easy interop with C APIs, but it seems it needs a FFI for that anyway.
Perhaps someone can enlighten me about that design decision? I'm sure there's a reason, I just don't immediately see it.
Although, gotta wonder how these stack-allocated objects interact with closures.
Maybe this wikipedia article has details: http://en.wikipedia.org/wiki/Thunk
var s string = "";
Now, I don't see it written there that it is on the stack, but I imagine so. From the source code of 6g, in cgen.c[2], line 884, you can see this comment:
/*
* n is on stack, either local variable
* or return value from function call.
* return n's offset from SP.
*/
Sounds to me that local variables and return values are always on the stack, which makes sense to me.[1] http://golang.org/doc/go_tutorial.html#tmp_44
[2] http://code.google.com/p/go/source/browse/src/cmd/6g/cgen.c?...
From what I read, Erlang is better at what Go tries to do.
Maybe it's just a 20% project that is being released into the wild...
BTW, Erlang's syntax has some annoyances that go beyond just not being C. "Ant turd tokens", for instance. Nothing that's going to stop a competent developer, of course.
I've already posted http://news.ycombinator.com/item?id=837217 to express my opinion on that though, if you want to read it.
It also doesn't have first class records. A record is nothing but a tuple, with some compile-time sugar that reminds you what the fields are. If Employee records have a name field, then you access it by saying e#Employee.name.
I'd love to see what Joe would do if he could go off and make an Erlang 2.0 and ditch the backwards compatibility.
Rewrite in the past tense, and this is an epitaph for any number of "niche" languages. Sad but true. Computer programming would be much better off if it were not so. Cultural expectations are a major factor in initial impressions. Good initial impressions make for a large, vibrant user base.
Python probably "gets it right" in terms of having enough syntax to satisfy expectations, but little enough to make tool writing accessible. (Except for the indentation thing, of course.) Ruby has too much. Smalltalk drops the ball with no precedence rules for math operations. Lisp and Forth are also a bit too weird, especially if your field is not programming and all you want to do is crunch some engineering data.
One could (and some are planning to) write a kernel in Go, doing the same in Erlang would be much harder, if possible at all.
Now Smalltalk and Lisp have both been used for "systems programming" -- years ago, on much older hardware. One can just live with the overhead. Go looks like it would have C-like memory overhead, so perhaps it is a much better choice in this regard?
For example (have to google for the document), a method dispatch on then comparable cpu's was 1000 microseconds vs 3.5 ms for Symbolics machine, due to the specialized instruction set.
Symbolics went so crazy, that it developed every HW piece being used - including monitors & printers :)
That to be said I love Common Lisp :)
Limbo is probably better, Erlang is not a systems/low level language, its aim isn't to come (anywhere) close to C performances, while Go seems to have performances in mind.
It is not "just a 20% project" (the list of people involved is quite big), plus if it was ken's 20% project, 20% of ken is like 20000% of your average hacker.