Go is amazing, period.
poincare101.blogspot.com
poincare101.blogspot.com
In addition to the cool things in the language, I really love what they are doing with the build system. The Go programming I've been doing has been on Windows but targeting an ARM CPU (the PXA168 in the Chumby 8 device) and cross-compiling Go code requires simply setting a couple of environmental variables. Sooo much nicer than having to set up a full-on GNU-style cross-compiling setup and using different toolchains for all your different targets.
eg:
set GOOS=windows
set GOARCH=386
go build
Just built my project for Windows x86.
---
set GOOS=windows
set GOARCH=amd64
go build
Just built my project for Windows x64
---
set GOOS=linux
set GOARCH=ARM
set GOARM=5
go build
Just built my project for the Chumby device.
---
I highly recommend checking Go out and looking past any of the superficial allergies you have to it (I'm historically a braces-on-their-own-line guy, so getting used to the strict enforcement of the other style was a pain for me) and giving it at least a few weeks to sink in. If it still isn't your cup of tea after that, then that's fine, but it is well worth a look, IMO.
Where do I find out more about the Windows port?
We've been working on Go 1 for about six months now, but have resisted pushing people toward the weekly (unstable) snapshots until the most recent one, as the documentation story was incomplete and we didn't want to leave newbies out in the cold. We're nearly ready on all fronts now, and hope to pull the pin on Go 1 before the end of the month.
And I suppose this small problem won't stop with Go1 as I hope we'll see new progress in weekly as we're used to.
Wait, what?
void func()
{
}
vs. void func() {
}
Does Go really enforce the latter? That would be incredibly silly.Go style is enforced mechanically with gofmt (http://weekly.golang.org/cmd/gofmt/), anyway, so one typically drops the pretension of these kinds of style quibbles. It is more important to have one consistent style than to make everyone happy. The gofmt style forced me to change several of my own habits, but it was definitely worth it for my code to look like everyone else's. I've never encountered a Go programmer who hasn't become grateful for gofmt, in the end.
Anyway, in that case I imagine we'll see a Go preprocessor that takes all the line-initial braces and moves them up a break before sending code to the compiler. People get pretty worked up about this stuff.
It's Python code and I find it uglier than some fairly large C++ project I used to work on.
Anyway, I wish there was a gofmt in Python because at least, I'd drop all hopes of forging my own rules (silly junkies) and some basic clarity would be forced into our codebase.
I know there are beautifiers but when such things are enforced and not negotiable, it's just so much simpler and people just stop caring as well.
I've always argued that if your team can't bother to even indent code properly than you have much bigger problems than any language formatting rules can solve.
We decided to make our build system run PEP over the code, resulting in a failure if PEP didn't pass.
It annoyed the hell out of him, but we quickly got the formatting up to a better standard.
I strongly believe that code should look like a screenplay, not a novel. More white space, in other words, is rarely a bad thing. Inline braces decrease white space and make unfamiliar code harder to scan, so to me they're Not Good.
Also wow, I didn't know it was even possible to write Python without spaces. Are we talking no spaces in arguments, like
def func(arg1,arg2):
print "Indented"
return
or full-on no spaces? def func(arg1,arg2):
print "Not indented"
return
I thought the latter was prohibited. def func(arg1,arg2):
i=other_stuff(1,2,3,4,56,43,234+4*3)
return iThe answer usually given is faster compile times and the removal of semicolons from the language. I don't know the details, but someone new complains about it on the mailing list fairly frequently.
Also having a tool enforced brace style is just plain practical. Less silly arguments/bikeshedding.
I was also a brace on its own line kinda guy, but between javascript and go, I've gotten over it.
Not that I have any experience with that...
a := 1 vs a = 1
With '=' I can "hyperthread" my typing. While I'm finishing the LHS and pressing space I can move my right hand to press '=', while keeping my left hand thumb in place to press the space bar for the right side.
With ':=' I have to stop everything to press shift with my left hand, then press ':', then release shift and press '='. It's very inefficient for something that happens often.
In the long run I'd say multiple assignment probably saves you more time writing declarations than an extra key-stroke would cost you.
My main gripe with := vs = is that as I change my code, an existing := may suddenly become invalid, meaning I have to go back and change it when compilation fails, or vice versa.
As someone who has been stuck writing JavaScript for Yahoo Widgets (Vizio Connected TV) over the past month, my appreciation for the compiler errors you get in static languages has grown tremendously. Previously I had taken them too much for granted.
if a == b {}
= is the usual assignment, := declares and initializes a variable inferring the type. var a int
a = 42
vs. a := 42
That means you'll see explicit types in variable declarations rarely.So, in other words, it's Amateur Hour. All righty, then.
/backs toward door, reaches for doorknob, still smiling and nodding
ROFL. I challenge you to find documentation for the C language or any other language commonly used in production where they speculate that they might wake up one day and change sizeof(int) on an existing platform.
"Fantastically dumb," indeed.
You seem very ignorant, please learn and stop the FUD.
Yeah, that must be it.
As far as the documentation for the C langauge where they speculate that it's not defined, just given a minimum bound: here you go: Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign (C99 spec, section 5.2.4.2.1)
It also allows sign-magnitude integers (complement 1) in addition to complement 2 (C99 spec, section 6.2.6.2)
It also doesn't define the number of bits in a byte (C99 spec, section 3.6 p2)
No, C doesn't define sizeof(int). It is implementation defined. But you don't change it once you implement it in a given development environment... not if you want people to create and maintain production code with your tools. You don't speculate that one day you might want to change sizeof(int). It's just not something you do if you want to be taken seriously.
Is anyone in this thread over the age of 16?
If you write production C code that depends on anything other than the minimum sizes defined in limits.h, your code is buggy.
For example, sort.Interface:
package sort
// A type, typically a collection, that satisfies sort.Interface can be
// sorted by the routines in this package. The methods require that the
// elements of the collection be enumerated by an integer index.
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less returns whether the element with index i should sort
// before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
It would have implications on array indices as well, since they are also int. void func() {
}
Is my natural choice anyway, so I guess, this will not stand in my way. Let's go!Having previously worked for chumby industries (makers of those bean bag alarm clock internet device thigies) I've got a nice collection of ARMv5 class devices laying around waiting to become useful and it is nice to have a modern language that is relatively low level support development on them. Quite a few other projects out there with arm support only care about v7+.
* author cannot write portable C sockets code
* author cannot handle C/C++
* author believes his app would be too slow in Python, later abandons App, but retains his bias against Python
* Go has no parens for if/for
* Go has unicode support
* Go has closures "like salt shakers"
* Go is cohesively designed
* Go has nice libraries
Go may or may not be a good language, but this kind of argument is not going to win me over.
There is a very strong difference between "cannot write" and the need for something to be simple.
I can definitely handle C/C++, and I don't think writing something in a higher-level language changes that.
If something is doing processing with 4000 threads with around 10 years worth of by-the-minute data, it sure as hell will run too slow in Python.
And, the arguments stated after are not crucial to "making you switch to Go", which was not the point of the article anyway.
EDIT: Also, I did not abandon the app, and in fact open sourced the Bayesian filter stuff I wrote right here: https://github.com/Poincare/Bayesian.go
But your arguments for Go rang hollow. I'd urge you to go through the "pro-Go" arguments point by point and describe why, say, they apply to Go but not to Python 3.0. And I'm not a Python zealot by any means; I mention it as a comparison point mostly because it's very commonly used.
There are undoubtedly lots of great reasons to use Go, but your article did not enunciate them in a way that would win people over.
That's sort of a terrible example since python is ill-suited to many (might I dare say a clear majority of?) production environments. The field of general-purpose production languages is actually pretty narrow. I somewhat agree with your point that the reasons were on the superficial side. Nevertheless, people are dissatisfied with the C/C++/JAVA trio and efforts to replace them have so far failed to stick (D comes to mind).
It's not like we're setting an impossibly high bar here. Just put forward a reasonable argument for why Go is cool. "Closures like salt shakers" will not win anyone over.
A bold statement, considering the broad range of production environments that have come to the opposite conclusion.
Do you have anything in specific to back up this claim or is this just name-calling?
Knowing Haskell makes reading about Go a very underwhelming experience.
Compilation times are not bad enough to be a problem.
This is what e.g. Haskell does, and Go as well, I think.
This is what Erlang does by default, GHC >= 6.12 will do it when using `+RTS -N -RTS` and Go requires explicitly setting GOMAXPROCS, the runtime defaults to single-threaded (as far as I know, GOMAXPROCS still hasn't been retired) and there is no way to have it auto-detect the core count.
I mean, if I want to write a cross platform websocket server signaling server for PeerConnection, what would you recommend that will let me write a statically typed server in 80 lines of code that's all standard libraries? (edit: Websockets was moved to a `go install`able package recently)
The author needs no age defense. He makes a ton of valid points for why you should try out Go.
Additionally, PyPy has many garbage collection algorithms, while Go has a stop-the-world mark-and-sweep collector.
Go is still really young, yet it's plenty fast. There's plenty of room for it to get much faster.
The problems with making Python fast mostly have to do with its complicated semantics, particularly around things like name lookup; the GIL doesn't have much to do with it.
Interestingly, I predict Go will have a much tougher time here, unless a form of goroutine is created that can't share any state at all. PyPy has been able to do a lot of garbage collection work precisely because it doesn't have to do concurrent GC. Unfortunately, Go crossed that bridge and can't really go back at this point.
I think he'll still have to learn a fair few tricks to get around some features of Go. Things like type assertions, float32 vs float64, get ready for it lack of generics, and no distinction between stack and heap aren't common in other similar languages, and just getting to know the standard library is a huge part of being productive in a language. C could be seen as better in that respect; the core language is _very_ simple, which can't really be said for Go, though the advantages of Go probably out weigh the advantages of C for many people.
Go doesn't have unions, though, and so this means that we would have ended up using a struct and using about 3x the memory on average, per stack value. You can see this limitation exposed as well in goyacc, the port of Yacc to Go (as the name suggests). Where Bison uses a union for yylval, Go is forced to use a struct.
I think this has been discussed on the golang-nuts mailing list a couple times and dismissed, for reasons of which I'm not fully aware.
You can simulate ML-style unions in Go with interfaces and downcasts, or the reflect package (basically like case classes in Scala, but without the exhaustiveness checking). Unfortunately, downcasts in Go (and interfaces generally) are slow.
From the tutorial: Every type implements the empty interface, which makes it useful for things like containers.
Unions are on the roadmap: http://golang.org/doc/devel/roadmap.html but it's a list of ideas rather than features promised.
The complaint I see here seem to be about c/c++ libraries. TL;DR; c is too level and boost sucks (ie, is too complexified).
Go sounds like one fine answer to this. I would claim that c++ with QT is another answer to this. Write parsers for DSLs quickly and easily with QT - its container classes work without nightmarish overtemplating, its string class is like an ordinary class, etc.
Edit: web.go looks pretty sweet: http://www.getwebgo.com/
Edit2: As does app.go: https://github.com/georgenava/appgo
...There's a large list of Go projects here: http://godashboard.appspot.com/project
http://gorilla-web.appspot.com/pkg/gorilla/mux/
If you want something more lightweight (Gorilla's not "heavy" by any means) there is pat (formerly pat.go)
The standard library gives you almost everything you need.
The http package provides a web server and client: http://weekly.golang.org/net/http/
The template package provides text templates: http://weekly.golang.org/text/template/ and automatically-escaped HTML templates: http://weekly.golang.org/html/template/
For other bits and pieces, see the rest of the standard library: http://weekly.golang.org/
I also recommend the Gorilla Web Toolkit for some other useful web-app functionality: http://gorilla-web.appspot.com/
So, how do you serve static files?
Can you drop the privileges from within go like apache or nginx are doing it?
A contributor to Go says otherwise if SSL is involved: https://groups.google.com/d/msg/golang-nuts/yohrNK8lFhc/L1d6...
It uses only the packages which ship with Go, with the exception of a Markdown parser. Unfortunately, it's written for an ~6 month old release of Go on Plan 9, but you can get the general idea of building Go web stuff. The code's a bit ugly too, but it does work.
The question is how do they overcome the opinion, hearsay and preferences that are louder than the truth?
Too few devs:
- truly give something 5 minutes before jumping to their foregone conclusion.
- admit that most languages with a decent capable and decent programmer are all, pretty equally equipped.
- every language + framework has it's pros and cons.
Type safety, easy concurrency, static checking, C-like syntax, fast compilation time, concise syntax, etc. Java is ripe for replacing as the default language for (new) large systems. The replacement could be another language on the JVM, but I think Go has a good shot.
By your definition, is Java type safe? You still need to guard against concurrent mutation of shared data in Java and in most other languages that support shared mutable state.
We typically describe Go as "memory safe," in that you can't address uninitialized memory (unless you import package "unsafe", which clearly demonstrates your intent).
By contrast, your Go program's behavior becomes undefined when you mutate and read a hashmap concurrently among multiple threads. Anything can happen.
Edit (addressing the reply below): That's fascinating, thanks. It really speaks to the wisdom of writing hash maps in the library, on top of the language, rather than unsafely in the runtime as Go does. (This would unfortunately require generics, so it's not an option for Go.)
It's very difficult to predict all that can go wrong with unsynchronized access to data structures that aren't designed to be thread safe. The beauty of Java here is that the core primitives can never lead to accessing undefined memory, and therefore hash tables, however badly they mess up, will never lead to that core principle being violated. This is critical for security, for example.
(sometimes type safety can be proven absolutely by static checking, but you have otherwise only run-time type checking, e.g. dynamic JVM languages, introspection).
Unlimited memory corruption does seem to imply that run-time type guarantees are gone, but it's still better to use the most appropriate terms.
Not exactly. Go's maps may safely be read from multiple threads simultaneously, but writing at the same time as reading or writing will yield undefined behavior.
Go programs don't segfault like C programs. They typically panic, providing a descriptive stack trace of where the problem arose.
As I mentioned in my other thread, what you're describing are "thread safe data structures," which Go doesn't provide by default. We provide the fast and non-thread-safe data structures and let the programmer build the concurrency mechanisms around them (easily done with a lock or using goroutines/channels).
Or do I miss something in your comment ?
EDIT : In my opinion, a program that doesn't crash and goes on running with inconsistent data structures is mainly hiding a failure which will appear in a worse way later (for example when those data will be used). To fail fast is often more secure. But my opinion may be based on the fact that I see too many java programs which seem to work but that nobody can touch because they're just in the lucky state where bugs don't surface too much.
(a) memory you don't have access to to be read;
(b) other threads to crash;
(c) the VM state to be corrupted;
(d) the GC to crash;
and so on. The Java world is still in a consistent state. In a security-oriented world, this is important.
To the reply: It's a bit pedantic for me to say this, I know, but that's still "a consistent state". Basically, a Java program can't do anything it wouldn't otherwise be able to do by modifying a hashmap concurrently. Java programs can go into infinite loops. They can't access uninitialized memory.
So next I looked at:
* http://golang.org/doc/go_tutorial.html
* http://golang.org/doc/effective_go.html
Way more than 5 minutes. Where are generics or do I have to learn some new construct? Wait a minute, is this thing object oriented or what? If not, why not? Do I have to learn some new philosophy? Already feeling a sense of dread having been through this game 10s of times before with other languages.
I decided to research a bit to see if anybody else with a C# background had looked into Go. I found this, which confirmed my feelings that Go is for people who probably haven't given C# or Java a fair chance: http://www.jondavis.net/techblog/?tag=/c%23+vs+go . That's when I also discovered searching for 'Go' on Google is impossible because of the poor choice of name and decided I wasn't going to spend any more time on it, already being aware that aside from what looks like a total philosophy change (without it being clear whether it'll be worth it), I'm going to lose out on my awesome set of development tools (Visual Studio), years of C# experience and the HUGE .NET ecosystem, in exchange for what? Relatively unimportant performance advantages?
At the end of the day, if performance/memory are issues I can just add more EC2 nodes to my architecture. At some point I'll hopefully make enough money to pay other people to worry about the technology. That being said I realize that as a developer who wants to be a manager/owner I'm probably in the minority of readers here.
> Way more than 5 minutes. Where are generics or do I have to learn some new construct? Wait a minute, is this thing object oriented or what? If not, why not? Do I have to learn some new philosophy? Already feeling a sense of dread having been through this game 10s of times before with other languages.
If you didn't get past the fact that Go isn't object oriented, then you clearly didn't get very far into the language. And your resistance to "some new philosophy" shows you aren't interested in a new language with real ideas, but at most a different way to express what you already know and do while programming.
My point is (a) I'm not a lazy developer that doesn't enjoy learning new things or experimenting with new languages and (b) I have found a great ecosystem in .NET and C# and I've been around the block; at first sight I simply cannot see a compelling reason to invest more of my increasingly limited time into learning Go.
If Go has great new vision or compelling difference from other languages then why isn't it there on the homepage at golang.org jumping out at me? All I see are technical details and a huge guide. While I applaud clear, detailed documentation, I'm not going to read through that documentation unless I have some idea of the payoff. I just spent half of my weekend researching and investigating a ton of message brokers for my current project because there's value in the outcome. Researching a new programming language needs to have a huge payoff, or I need to have lots of free time (which unfortunately I don't).
There is absolutely nothing to sell me on the language on the homepage, or in the OP's blog post, and nothing to distinguish it from the 10s of other new languages out there. The FAQ touches on the fact that e.g. it's not object-oriented but not WHY. It just mentions "interfaces" and says "we believe". So I'll have to go and play with it and build something substantial to find out what they might be talking about. The goals mentioned in the FAQ are really not interesting (have you read it?) - perhaps the ideas around concurrency are convenient but they are limited in scope and don't directly address the more complex concurrency issues better than my current platform that I'm facing while I build a web crawler.
To be clear once again: It may be that Go is absolutely amazing and awesome... but if I had to spent days looking into every new language that pops up on the Internet I would never get anything done, and this is the point I was trying to convey in response to the parent's post. It's still on my list to look into but I just don't have a week to commit to what looks like quite a lot to manually digest.
But after all of this I think I'm going to have to write one of my site-specific crawlers in Go for fun; since Go has a STOMP binding it should be easy to integrate into my existing architecture. Where things will get interesting is finding a compatible serialization library (and so we start getting into the real world problems of using a new language to solve interesting problems... hopefully one of the .NET protocol buffer implementations will work correctly with the one I imagine exists for Go).
That's one of the primary points of protocol buffers ;-)
"Why does Go not have generic types?
Generics may well be added at some point. We don't feel an urgency for them, although we understand some programmers do.
We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it. Meanwhile, Go's built-in [functionality] mean in many cases it is possible to write code that does what generics would enable, if less smoothly.
This remains an open issue."
Clearly the designers of Go consider generics a topic worthy of debate.
Your comment about "real-world" code is even more puzzling, as if all "real-world" code is somehow equivalent in abstraction needs. There are guys who've written serious code running in billions of cellphones where generics would be unimportant. Same thing for scientific or massive data crunching applications, e.g. Google's infrastructure.
In the space I work in - enterprise applications integrating large, disparate systems where you have zero control over interfaces and data formats but somehow need to get everything talking together nicely, generics are invaluable in structuring your code and making it reusable.
To be fair, I happen to be building a little search engine of my own and Go may turn out to be great for building the crawler components (the processing is site-specific), and I may end up using it for that purpose if I have the time to explore it or see value in it (if I find memory pressure to be an issue then saving 1/3 RAM on my EC2 instances over C# is a definite win, but since most of the work is I/O constrained I may never run into an issue at all).
Luckily for you, Go already solves these problems incredibly naturally! Unfortunately, you haven't looked into how Go solves those problems, primarily through its interfaces and type embedding, plus its slices and so on are already generic.
It's true they aren't sure if they need it or not, but you clearly haven't looked into many feel they are unnecessary and that the present language is more than sufficient for solving many needs. In fact, Go is almost explicitly designed to handle the production cases you tackle. But it seems you've said in other threads that learning new approaches isn't really worth it for you, in which case, it's unsurprising that new languages aren't offering you much.
Ultimately we will find things we like, or are willing to suffer and cover up (true in every community).
It's just how open minded we really are.
What? I'm a student still learning new languages and it took me no time to look up and quickly grok duck typing. If that prevents you from learning a language...
Seriously... it's an hour to skim and read through. Hour or two to put together a decent non-trivial server demonstrating channels. I really don't know what your big long rant is about. It's not hard to find reasons Go was designed the way it was, find what it's goal is and read enough intro docs to get up and coding with it easily.
I don't want to sound smug, so I won't mention any languages I'm comparing to — but seriously, unless you've been living in Python-land, those things are nothing to write home about. I'm surprised this is getting so many upvotes.
If I were to praise Go, I would concentrate on something innovative — concurrency primitives are interesting, for instance. I would not consider them sufficient for all applications, but they are intriguing and worth discussing.
I intended to say that Lisp's and Go's both performance and succinctness in the wild are probably on par. But Lisp is already there for a long time.
And I don't understand the comment about things being "precompiled". So what? Compilation is a natural step. Note that with most lisps "compilation" is not something you wait for while your server farm keeps crunching .c files, it's a natural step, sometimes happening behind the scenes.
Since I've posted a link to Shootout comparison of Go and Common Lisp I thought I made it clear which Lisp I was talking about.
> And I don't understand the comment about things being "precompiled". So what?
It means that a descent part of the computation was done in the compile (macroexpansion) time and this time was not measured and included into the total result. This may be great for cheating Shootout benchmarks but does not fairly demonstrate the performance of the language.
What are you talking about? Most every single evented io library out there just boils down to a single system call in the underlying language - C: epoll(or select, poll, or kqueue) on socket/file descriptors. You do know that socket() returns a socket, which is actually just a file descriptor, right? You don't need libev and libevent because you can just write your own in two seconds with epoll! And if you're really attached to having the library handle the work for you you can always use one of the many cross-platform event libraries, like Glib which, last I checked, works on Win32, Mac, and Linux.
PyPy, Cython or Shed Skin might have been answers to those number crunching problems. I'd love to learn whether they would be sufficient for OP's performance requirements. Some benchmarks look promising, for instance this one published in late 2010: http://geetduggal.wordpress.com/2010/11/25/speed-up-your-pyt...
However, Go's goroutines are IMHO superior to Python threads since they're much more lightweight and can run in parallel on multi-core CPUs and you can have a lot more of them.
Go gets it right by putting goroutines and channels into the core language to encourage CSP style concurrency, but putting other more traditional, but harder-to-use, concurrency primitives like mutexes into the standard library.
> its standard library queue class (http://docs.python.org/library/queue.html) is very close to Go's channels so it does CSP style concurrency quite nicely.
Among other things, it lacks any construct similar to Go's `select`, without which channels are nowhere nearly as useful.
And then there are issues like what you point out about how incredibly cheap goroutines are.
Is there any particular reason for that or is it just that not many have got around to doing it.
A type-inferred language with first class functions, with strong support for parallelism, and good support for arrays and slicing seems a really sweet deal. Throw in SIMD and it is already very compelling. Is anything wrong with the picture that I am missing. Performance issues ?
I think the primary reason for the lack of users has been language stability. The Go team are currently working on the first actual "release" of the language ("Go 1") to address this. But prior to the move towards Go 1, the language was very much in flux, more so than you'd want for a language (that you'll actively be maintaining code in) to be. (And gofix, while nice, isn't really a substitute for language and standard library stability).
I agree with you in principle but practically, gofix (+ gofmt) it is pretty darn close. I revisited a Go project that I wrote back when it first came out (in other words, an ancient one :). Biggest pita was dealing with the 'error' changes that gofix couldn't fix (and some minor pain due to time and Duration), but everything else was taken care of by the tool.
In any event, my understanding is that the Go authors will strategically depend on gofix to deal with language evolution (beyond "Go 1").
I've been coding since '82 and have had my share of PLs. Go is a serious contender and I highly recommend it to anyone looking for a "modern" C.
In my experience, a stop-the-world collector that must be threadsafe ends up being a disaster. You hit a brick wall in terms of real-time performance quickly (look at iOS versus Android for an easy example, and Dalvik's GC is much more sophisticated than that of Go these days).
I predict that Go is going to have to put a lot of effort into making the GC fast in order to compete with C++ and Java. They're going to need a concurrent, generational garbage collector much like Java's, probably with a server mode and a client mode. It'll have to be heavily tuned and will require man-years of work.
Go data structures tend to be much smaller than the Java equivalents, and it is much easier to track down and eliminate unnecessary allocations in Go code. When you have better control over allocations you don't need to lean so hard on the garbage collector. (Some of this is touched on here http://loadcode.blogspot.com.au/2009/12/go-vs-java.html)
You seem to have a lot of strong opinions (and predictions!) about Go, when you clearly don't have much experience with it.
Besides, once you have a stop-the-world multithreaded GC, it has to trace all the roots in the program for correctness. There's no way around that. At that point having all the data on the stack doesn't help you (except for cache locality, but Java's GC already does that via the nursery and copying during major collections). You must still trace every pointer in the object graph, while keeping all threads suspended. You can run the GC less often, but that's not much of a help when interactive performance is at stake. iOS feels so great because the UI is always running at 60 frames per second. Stop-the-world GC can't do that.
I don't know why you claim that "having all the data on the stack doesn't help you". That makes no sense. If data is on the stack, any references starting there disappear as soon as that stack frame is popped, so there's no lingering work for the GC to do; the GC arena is unchanged.
Your comments strongly imply that you have no practical experience with Go's GC. I suggest you stop claiming that it has certain performance characteristics or behaviours when you have not experienced it yourself.
You're only considering the sweep phase. Sweep is the easy part of tracing GC - you can always chuck sweep into a background thread. The mark phase is the problem. Marking always has to trace roots, including stack roots - that's how GC works. Tracing GC never traces dead objects.
You can reduce allocation pressure by using the stack, which will make the GC run less often, but my point is that when it does run you're no better off than Java, and quite a bit worse since Java's GC can run in parallel with the mutator and Go's can't.
"Your comments strongly imply that you have no practical experience with Go's GC. I suggest you stop claiming that it has certain performance characteristics or behaviours when you have not experienced it yourself."
I have experience with GC generally. There's nothing particularly special about Go's GC: it's a standard stop-the-world mark-and-sweep collector for a language that supports a limited form of stack allocation but generally uses heap allocation. The performance characteristics that this form of GC must have are well-known.
If you want data, look at the binary-trees benchmark: http://shootout.alioth.debian.org/u32/benchmark.php?test=all...
It's mostly a test of GC. Java's GC runs more often (thus the memory use is lower) and yet it's still 4x faster. This is because Java has a generational, concurrent-incremental collector.
The gc compiler does perform some optimizations, including inlining across package boundaries. There is also the gccgo compiler which takes full advantage of gcc's many optimizations. Both compilers will be equally supported in Go 1.
Not competitive with "modern C and C++ compilers"? There are few real world programs that are improved by code generation micro-optimizations, and even for those that are Go is still competitive. http://blog.golang.org/2011/06/profiling-go-programs.html
I don't know how to convince you of the fact that this statement just isn't true. Consider the rasterization software you're using right now in your web browser. Micro-optimizations hugely matter for blitting and tessellation. Consider video decoding (or encoding!). Using SSE instructions instead of going word-by-word or byte-by-byte makes an enormous difference. Read Dark Shikari's blog posts about x264 if you want to see how much good use of SSE matters for video encoding.
To name just one example: Modern x86 processors have an optimization that allows the fetch-and-decode step to be skipped for the second and subsequent iterations of small loops. By "small" I mean "really really small" -- something like 16 bytes is the number I've heard. By shaving a byte or two off the instruction encoding to fit a loop from 18 bytes into 16 bytes, the loop performance can double or triple. When that loop is the loop that drives alpha blending on your touch-sensitive mobile app, that can be the difference between an app that feels solid and fluid and an app that feels slow and pokey.
People use systems languages for performance. Folks for whom performance is irrelevant are all on dynamic languages, and that's not changing. Systems programmers need a compiler that knows about these micro-optimizations.
> Systems programmers need a compiler that knows about these micro-optimizations.
And they have gccgo! Yay! :-)
Most of the code in any program is not performance critical. Yet the reason that this is the case is that most of the time of any program is spent in tight loops. Those tight loops are what must be optimized. And that is why performance-minded systems programmers use top-notch optimizing compilers.
The popular dynamic languages have gotten away with being relatively slow because programs written in them are either not CPU bound or spend most of their CPU time in C libraries. This works great for them -- dynamic languages are awesome! But the calculus changes when you're programming in a language that defines the entire stack. When there's no C-compiled code to fall back on, micro-optimizations start to matter.
Like http://x264dev.multimedia.cx/archives/486? "Now that I’ve written a thousand or two lines of assembly code..." etc. Programmers who know and care about these processor-level micro-optimizations use assembly code, for which by definition you do not need a compiler.
Then again if you really care about graphics performance, you're using a GPU in which case there is no compiler since the driver is just an opaque binary blob.
And a huge amount of graphics processing is always done on the CPU. Unless you're using Direct2D or something, rasterization is always done there (and even if you're using Direct2D, a lot of rasterization is still done there).
(Outside a function, every construct begins with a keyword and the := construct is not available.)
===
Why is that? I would find that frustrating and inconsistent.
Go sounds like a great language for someone with my background to be able to work with a closer to the metal language but by handling some of the more difficult aspects of working with C like memory management and pointer arithmetic.
package rand
/*
#include <stdlib.h>
*/
import "C"
func Random() int {
return int(C.random())
}
func Seed(i int) {
C.srandom(C.uint(i))
}
So calling C functions from Go is very easy. However the other way is not supported, AFAIK.Python doesn't enforce any parenthesis in those statements, so how were you using them in Python that changes how you'd do the same thing in Go?
I'll try to build my next project on top of github.com/codahale/dropwizard
There are others, [2]
I mean, there certainly isn't a complete equivalence of Eclipse for Go (yet?).
[1]: https://github.com/nsf/gocode
[2]: http://go-lang.cat-v.org/dev-utils http://go-lang.cat-v.org/text-editors/ etc, etc
By comparison, JavaScript lets you structure your code in however you like, and there is a very tiny standard library and no real uniformity across implementations, frameworks, and so on. This can be a strength, but I think on balance it is a real weakness in JS. node.js has done a lot to improve this, though the language itself still lets you define anything, anywhere, at any time, and change that state from anywhere else.
Not true with ES6 modules.
Besides, Python and Ruby have open modules, and that hasn't hurt their usefulness in the real world. Quite the opposite, actually; one of the great pragmatic strengths of Rails was that it monkey patched Ruby's standard libraries. It's hurt optimization, but that's a different story.
if you want to learn a new language, actually learn a new language. learn a language that's actually breaking the mold in terms of how we communicate with computers. think at a higher abstraction level than dynamic dispatch and composable objects and subroutines, that stuff is already more than 40 years old.
http://www.thocp.net/biographies/papers/backus_turingaward_l...
[1] I think it's silly to imply that languages are "better" than one another. Some are more apt for certain projects and some have different feature sets that appeal to certain people. Certainly it seems unrealistic to absolutely call a language useless, especially given the points in this articl.
You seem to value "breaking the mold" for the sake of "breaking the mold" Or, you didn't give a good reason to value it.
"that stuff is already more than 40 years old.". Is this the fashion industry? Or do you believe that quality is a function of age?
"i truly believe go contributes negative work to society"
the fact is that go touts itself as a C++/java alternative but i see no significant/non-superficial reason to actually change languages. thinking in go is 99% the same thing as thinking in C++. consequently, 99% of the time doing stuff in go takes me roughly the same amount of time as doing the same thing in C++. programmers remain stunted.
we all know how efficient we can be writing code like in the von neumann style (not to mention 90% of programmers haven't yet even mastered that). to advance what people can do with computers it's time to start thinking beyond sequences of instructions and memory accesses, we need a language that encourages higher-order thinking. otherwise it's like building the empire state building with legos.
2) One line counter-example to disprove your negative-work argument: goroutines. Also known as: CSP-style concurrency in a procedural language.
I urge you to read up on goroutines. There are quite a few examples on the golang site of how you can use this feature to good effect, examples that would require you to think very differently than if you were in C.
Also, I'd like to point out that the Go project got started because Rob Pike and Ken Thompson grew tired of long build times while working with C++ while at Google. One of Go's objectives is fast compilation times. They are willing to stick to this goal at the expense of complex type systems. This is, if it is anything, not negative work.
Java: java.util.concurrent
.NET Task Parallel Library
C++ Parallel Patterns Library Threading Building Blocks Click Cilk Plus
D Actors + std.concurrency
Erlang Actors
Scala Actors
Haskell STM
Clojure STM
There are good things about Go, but people should learn other programming languages properly, before doing comparisons.
Among your examples, those that are comparable to goroutines are all for functional languages. There's nothing wrong with functional languages, but it's far from "all mainstream languages".
Fibers are for cooperative multitasking so no parallelism either.
Goroutines are multiplexed as needed onto system threads. http://golang.org/doc/GoCourseDay3.pdf
So they are a bit different, in the spirit of Go: they make for a simple and general solution to both parallelism and concurrency. They combine naturally with channels to give the functionality of OS threads, user threads and fibers.
threading (or CSP) is nothing new conceptually. yes, i agree, the go language has popularized a cheap threading implementation but the same design concepts we've applied to unix processes and posix threads apply to goroutines.
btw, blocks in ruby and generators in python have existed for many years prior to go.
If you want a fresh look at systems programming then leaning Ocaml or Haskell would be a much better option because you will learn to solve problems in a new way, not just with slightly different syntax.
Also, someone on this thread doesn't understand how downvoting works. If you disagree with something then make a response, save downvotes for deliberately trollish or off-topic comments.
One thing I really like in Go is how small the language is.