Having bet my entire startup on Go, I am really thankful for the steady, but measured, improvements to the language. It's been a real pleasure to work with.
It may not be as beautiful as CoffeeScript (which we also use), as rich as Python, as safe as Rust, as concurrent as Erlang, or even as hackable as Ruby, but it certainly offers an unparalleled set of features which is hard to find in just one language — decent standard library, decent syntax, decent performance, super easy concurrency, a helpful and reasonably sized developer community, a relative level of stability, automatic memory management with good enough control over memory use, usable interoperability with C, native client support and even a standard testing framework.
Thank you and happy birthday to all the fellow Go developers out here on HN.
Although I have used Go in the past and do like it - thought I would just point out that nearly every positive about Go you mentioned had 'Good enough' prefix it. Are you actually finding Go good or only enough for your current needs?
As a question: do you see parts of your startup expanding past the area of Go? Would a mixture of other languages help?
Great question Stuart. I'd first like to say that in today's environment, it would be insane not to take advantage of a mixture of languages. If you have the expertise within your team, you should definitely leverage the strengths of the various language eco-systems. We've been developing an RPC-like system (think ZeroMQ meets BERT-RPC) so that services can be written in whatever language is most suitable — Go, Python, Ruby, CoffeeScript, Java — and our datastore core is written in C. Hell, we're even working on our own object-capability language using PyPy's translation toolchain.
But, having said all that, the biggest surprise has been how Go has become the dominant language within our code base. We initially started using Go to just handle the networking layer. But it soon became apparent that Go was perfectly viable as a general purpose language. And today the majority of our code is written in Go.
So, whilst we'll continue to leverage other languages for what they are good at, I can confidently say that Go will be at the heart of our technology stack for the forseeable future. And with the various "good enough" statements, I was trying to say that although Go is not the best language ever for specific features (e.g. syntax, standard library, etc.), it definitely offers the best all round set. And the situation only gets better every day. So I'll definitely say that Go is more than good enough.
Is interop with C an important thing? Isn't Go supposed to replace the need for C. Is it just because Go's compilers aren't mature enough yet that you still need to drop back to C in places?
It continues to amaze me how much is packed into the Go language. It's not perfect, but the language specification is something that you can easily read in one go; something that is impossible for languages like C++. This results in more intuitive behaviour and, in my limited experience, fewer bugs.
I hope other language designers take note of Go and put more emphasis on simplicity in the future.
I would also be very interested to know which companies are using Go, and for what.
A relevant quote from a (relatively academic, static typing-oriented, functional etc.) sector of the language design community:
Google is hiring people to design languages and tools that know absolutely nothing about modern language design techniques, or what modern software engineering tools look like.
If you're paying any attention at all to Go, you're not learning anything. In fact, it's possible you're damaging your brain. It's projects like these that make Google look really bad and unattractive to programming language researchers, especially as compared to Adobe, IBM, Sun, and Microsoft.
Hahaha. I'm an academic but I still laugh because we are so horribly arrogant and yet quite oblivious. We always introduce our papers and grants with "this is a very important problem with applications in blah blah blah" but we honestly have no idea what that really means or if it actually is the big problem for engineers (as opposed to an annoyance) and go on to do present our work developed in a bubble and tested on whatever we have access to in our labs. Consider erlang, such a language would never come out of academia. It's far too focused on reliability and maintenance. Those two problems are never on our radar in any real way.
On the other hand, the academic community seems to have a fairly narrow outlook on programming language design. Go seems to be more concerned with ergonomics than provability, which seems like a reasonable decision from where I stand.
The academic community is - almost by definition - focused on doing "new stuff". That means, for example that they have a significant focus on getting type systems correct, but often consider things like integration with existing 3rd party libraries uninteresting.
You'd never see a language like Perl, PHP, or even Javascript come from the academic community because they don't break any new ground.
>You'd never see a language like Perl, PHP, or even Javascript come from the academic community because they don't break any new ground.
No, you'd never see these languages from the academic community because they're horribly designed. They design betrays someone who has learned nearly nothing from existing languages as they all make mistakes that were encountered and solved decades ago.
>>They design betrays someone who has learned nearly nothing from existing languages as they all make mistakes that were encountered and solved decades ago.
But... the whole point with the popular scripting languages is that they are easy to pick up -- just because they are heavily influenced by old languages!
(Besides, it is one thing to copy features from existing languages -- doesn't imply there is nothing interesting in the new languages. [Edit: Not all, at least. :-)] )
Edit: Here is an example of the last case:
A few years ago, I heard a talk about Moose, a replacement for OO in Perl (by Yuval Kogman/"nothingmuch"). There were two main points (1) Moose is stable, (2) it is modern. "And with modern, I mean the latest research papers".
>just because they are heavily influenced by old languages!
They show signs of knowing about older languages but not understanding them. For example perl has dynamic variables (this is a huge win and for me the only good thing I have to say about the whole language)... but they're default. We had already fought this out in Lisp and found out that while they're an incredible concept and should be in any language that favors mutating variables, dynamic variables should not be the default.
Python using crappy one line lambdas instead of real closures. Why? Because Guido seems to not get functional programming. Ruby copies Smalltalk but Katz says Smalltalk "goes to far". What? A lot of the problems that trip people up in Ruby aren't a problem in Smalltalk. The biggest difference between the two is that Ruby isn't image based, but Smalltalk doesn't have to be either.
For me the biggest problem with the scripting languages is that they don't have any need to exist. They usually copy features from existing languages that already did a better job. If the manpower they got had been focused on the source languages the communities could have gotten a lot farther.
>There were two main points (1) Moose is stable, (2) it is modern. "And with modern, I mean the latest research papers".
The papers he was talking about were likely the Traits papers. Traits were done first in Smalltalk and aren't needed in Lisp because CLOS has proper multiple inheritance. Moose does look ok though.
>>problem with the scripting languages is that they don't have any need to exist. They usually copy features from existing languages that already did a better job.
All I've read (and own experience), says that scripting languages are much faster to develop with?
>All I've read (and own experience), says that scripting languages are much faster to develop with?
Well, your throwing me an anecdote and asking me to contradict it so I guess I can do so with an anecdote as well?
"Faster to develop with" isn't a sign of a properly designed language and it certainly doesn't justify the language existing. It only speaks to the packaging of said language.
I think we can find a great example in PHP. I think we'd be hard pressed to find someone that would suggest PHP is a well designed language [1], yet it uprooted perl and took over the web. Why? Because it was less effort to go from zero to working web application than anything else. If the creator of PHP had, instead, created his platform on Lisp (and excluded the poisonous Lisp IRC community), who knows, he might have had even more success because Lisp is better designed, actually existed, etc. [2].
[1] But this is the Internet after all, so I'm sure you could find some one who would say that.
[2] Of course you might say "yea, but it's hard to get Lisp running on new servers" and there is truth to that, but PHP didn't exist at all. Surely it would have been at least comparable effort to fork some Lisp project and create "PHP" from that.
Consider code size, which is easy to measure -- and examples are over the net. Compare e.g. C/Java with the usual suspects (Ruby, Perl, Python, PHP, etc). For many applications, the scripting code is half the size.
A given programmer tend to produce a certain number of lines per day. Ergo, shorter coding time.
Coding time with an edit/compile/test cycle might be offset by modern IDEs (I have no data on this).
>>"Faster to develop with" isn't a sign of a properly designed language and it certainly doesn't justify the language existing.
Coding size costs money; both to write and to support. Money is one of the big motivators today...
>>[2] Of course you might say "yea, but it's hard to get Lisp running on new servers" and there is truth to that, but PHP didn't exist at all
I don't know much about PHP, but it is well known that the first version was written as Perl scripts.
(I don't know, does Lisp really have such problems with its community? Write anything bad about Python and you'll get flamed to a crisp, Ruby has a lots of childish rah-rah etc.)
I agree with your overall argument that less code = better. What I don't agree with is that that conclusively demonstrates good design. I think all of the scripting languages have design problems that were solved before the languages were ever written. For what it's worth, I don't consider Java well designed either. All of it's insights already existed elsewhere [1].
Lines of code is also a bad metric. You have to also count characters, etc. There was a study that did just this for C++, Java and Smalltalk. Java was 3 times more concise than C++ and Smalltalk 3 times more concise than Java.
[1] Interfaces would be the closest Java was to inventing something but Smalltalk had these informally (and some environments would let you work with them directly).
>>I think all of the scripting languages have design problems that were solved before the languages were ever written.
I don't disagree. But many/most of those design decisions were made to ease learning path, etc.
I should know by now that it is hard to argue "worse is better" to a CL guy. :-)
(C++ is quite a bit more flexible than Java; what feature took so much more characters? afaik -- with modern libraries, you can be very productive in C++. It isn't used so much because of the pain, I guess...)
> All I've read (and own experience), says that scripting languages are much faster to develop with?
Much faster to develop with than what is the question. Much faster to develop with than C++? Or Java? Sure, but that's not a very impressive benchmark is it?
Not really, at least not from an academic point of view. C showed up a few years after languages like LISP and Simula and around the same time as Prolog. Those languages are far more innovative than C. C on the other hand basically took well known concepts from BCPL and PDP Assembly and improved on them and made them portable.
Unix was basically a simpler, easier to use version of MIT Multics, designed for the smaller and cheaper PDP-7. Most of the innovative ideas in Unix had first implemented in Multics.
So while neither C nor Unix where truly innovative, even for their time, they won out because they took well known concepts and actually made them work in a practical sense.
If you read on, on LtU, someone suggests that they discuss Go on its own merits instead of making statements about the hiring practices of Google and Z-bo agrees.
Interesting quote. But since Go is meant to be a "systems language", and the (only?) others are C and C++, which first appeared in 1972 and 1983 respectively, I can confidently assert that "modern language design techniques" are not all they're cracked up to be.
Moreover, I care not one whit that Google looks "really bad and unattractive to programming language researchers"; because I'm not one.
Some people have used OCaml for systems work, and it's a lot more "advanced" in a programming language theory sense. BitC also looks more ambitious than Go.
That's the problem with designing and implementing an ambitious programming language: it's harder. Which is one of the reasons that Go is being used to develop real applications. I don't think the same thing can be said for BitC.
> Which is one of the reasons that Go is being used to develop real applications. I don't think the same thing can be said for BitC.
Until BitC author claims that it is used for real applications. Has anyone outside of the Go team mentioned any use of Go in real applications? Please correct me if I am wrong, but at the moment Go, BitC and Rust are all experimental systems programing languages.
Yes, but has anyone other than the Go development team claimed so? Even in Google, has anyone outside of the Go team mentioned using it for writing production systems?
There are various companies outside Google that are using Go in production, if you read elsewhere in this thread somebody pointed out they had pretty much bet their starup on Go and they are using it as their main development language.
I definitely had plenty of complaints (there's no way in the language to detect when a process exits, for example -- though you can at least build one yourself).
I don't think LtU approval is necessary to have done something good. We need more tools that help programmers solve problems of concurrency without losing their feet.
Tools that aren't entirely groundbreaking are very useful here, because you can take a guy who knows only c++ and have him write a bit of go. I can't as easily get him to use twisted or erlang or even node.js.
I still think go is as it is because the want as many C/C++ Programmers as possible. They could have done a better language (it is ok already) but probebly a less successful one (to bad C++ and Java messed up most programmers).
I used go recently when I needed to write a test case when trying to exploit a specific suspected bug. https://github.com/dustin/gohammer
It was successful in that I found it very easy to express what I wanted and make a concurrent app to do it. It didn't actually find a bug (I'm not entirely sure there was one, but the code that fell out of it is reusable for my next one).
When go first came out, I wrote a memcached server in it: http://dustin.github.com/2009/11/12/gomemcached.html -- the language was a little rougher when I started the project (defer didn't work properly until last march), but I still feel pretty good about it.
From the tutorial: "The language forces the brace style to some extent."
Well, that's it. If I can't have a brace-war tearing the dev group apart for months and kill productivity, I want nothing to do with that language. What's next, significant white space?
Hopefully with people from the dynamic languages camp trying the language they'll clean up the syntax. It's ugly and makes a lot of the example code hard to read.
Syntax is never really a problem. We do a lot of work in Erlang...
Erlang is based originally on Prolog, a logic programming language that was briefly hot in the 80's. Surely you've seen other languages based on Prolog, right? No? Why not? Because Prolog sucks ass for building entire applications. But that hasn't deterred Erlang from stealing it's dynamite syntax. [source: http://damienkatz.net/2008/03/what_sucks_abou.htmlWhat Sucks About Erlang]
In reality, syntax just fades away after ~5 minutes of real world usage. As Steve Jobs would say, it's not that big of a deal.
Erlang's syntax isn't representative of Prolog's. It was originally implemented in SICStus, sure, but Prolog lets you add your own operators, and Erlang added a ton on top of the (rather clean) Prolog syntax. How would Ruby (or whatever syntax you like) look if you made a DSL by adding every operator that wasn't already in use?
You know all the problems with the ambiguous ; , . stuff that Katz gripes about in that post? Prolog terminates every clause with a period, and all related rules just occur in sequence. Prolog has a read function, much like read in Lisp - "read the next complete (s-expression|Prolog clause) from stdin". The original Erlang compiler needed to read all of the alternative clauses for a function in one go* , so they strung them together with "," and ";", which are Prolog's and and or operators. (They could have fixed this when they started self-hosting, but probably had other priorities.) In practice, it isn't a problem (and Erlang has many perks to make up for those minor syntactic irritations!), but that can't be blamed on Prolog. It's sort of like if you used Lisp's (read) to load more expressions, but since your compiler needed you to read a whole module at once as an implementation detail, you used [ and { pairs instead of parens. Yuck!
* I'm reading between the lines here, so if Robert Virding swoops in and tells me I'm wrong, Hello Robert! :)
If anything, the reason that Prolog isn't good for entire applications is that it's fundamentally a rules/database query language. It's awkward for stateful / procedural code, but if you treat it like (say) a much more sophisticated SQLite, it will be good to you.
It fades away, but lags there chipping at productivity. The Ruby crowd makes a big fuss about their syntax, talk about how it revitalized their love of programming, makes programming enjoyable and so on. They might be onto something.
I agree that the Go example code looks ugly, although much of that for me is simply from their ideas on capitalization. Of special note from my perspective is that their biggest attempt to clean up syntax, by adopting a JS-esque automatic insertion of most semicolons, has backfired: it doesn't make anything prettier, it's either a wash or a slight loss with respect to obviousness of code, and it introduces a few opportunities for bugs. Perl of all languages did a better job at this goal by just making the terminator of the last element of a block or list optional.
I appreciate their maintenance of an end delimiter to blocks that is vertically aligned with the start of the block, although they could have gotten a bigger win imo by going with the ALGOL/Ruby style 'end' rather than the C style curly brace (and in doing so freed up curly braces to unambiguously be used for something else).
Yeah, that was likely a big mistake on their part.
Arguments on significant whitespace aside, I think that this is one thing that Python got right. (For reference, Python's rules are that ending a line with a backslash will continue a statement, and the same effect will occur automatically if you have a parenthesis, curly, or bracket open.)
I might also be convinced that it would be a good idea to have statement continuation happen if the last token on a line was a binary operator, for the benefit of code like:
if self.foo() and
self.bar() and
self.baz():
do stuff
(Currently PEP 8 requests that you put parentheses around the test.)
Go's public/private difference is capitalization of method names. That's hard to scan. Then you get chains that look.Like().A().Mess().
What the Go team seemed to do was take syntax from other languages they were familiar with, ugly syntax non-dynamic languages. They didn't focus on it, Pike said it wasn't important, semantics are important. So when you don't design syntax first, you get a syntax that's on the opposite end from Ruby.
Arguments func([] byte T* blah), who knows what goes where. That needs work.
The c-> and <-c is unintuitive, the syntax is so itsy bitsy it's easy to miss the difference. They should have keywords for that.
And in general the syntax is itsy bitsy, they feel that shorter words means quicker to read, but it's an overreaction to never ending lines commonly found in Java and C++.
I love capitalised public method names. It means I can immediately tell whether a method is public or private, in any context, e.g. on code pasted on HN.
look.Like().A().Mess() looks awful. Don't do it. Or do, it's up to you/ your company's style guide. You could easily avoid chained methods entirely.
Go is at the opposite end from Ruby. It's a systems language... The fact that they look different is no surprise.
func([] byte T* blah) - that's not Go.
send and receive are perfectly intuitive to me. Watch! You put it in the channel<-. You get it out of the <-channel. There is no "->".
"in general the syntax is itsy bitsy" - I can only suggest you try it for a bit longer until you get used to it.
Yea I don't use Go, tried it many moons ago, those were my impressions of the syntax, was going to edit with real code.
Rob Pike made an interesting argument about dynamic vs compiled languages. Said that the division between easy of use and performance, dynamic interpreted vs static compiled was not caused by technical problems, just dumb luck. People that made up dynamic languages weren't interested in performance, didn't design around it.
Maybe now they're perpetuating the same division in syntax. System language syntax is weird, machine looking, dynamic language syntax reads more like English. Doesn't have to be that way, but it would be the system guy's preference. So I was thinking if the dynamic language camp used to Python's syntax took up Go, maybe it would be changed for their taste.
The channel <- syntax is crazy. In and out depends on which side of the operator channel is in. I'm sure they thought it was cute, but "into" "out" keywords are easier to keep track of than which side the channel var name is on.
"System language syntax is weird, machine looking" - But if it's your job to program in C/C++/Go, you begin to read the code just like English. Go's syntax, you will admit, is much cleaner than C++'s. Personally I like blocks of code being separated by curly braces, I think it helps keep them separate. Combined with Gofmt, which automatically indents code (like Python), I find Go very readable indeed.
I don't understand your objections to the channel syntax; the order of the letters you type matters, obviously. Again, it's a personal preference, and I'm quite used to C's pre/postfix operators.
My objection is aesthetics. It's subjective, a matter of taste.
I prefer languages that you don't have to get used to. They're obvious, like a good user interface is obvious. Anyone can read their code, even if they don't work in the language. Go could be a language like that, there are no technical roadblocks for doing that, just a matter of the audience's taste.
Most people would consider Lisps, Perl and JavaScript to be dynamic languages. The first two are commonly thought to have "weird" syntax and the last has a C-like syntax --and C is the main example of system programming language. (Maybe JavaScript is a bad example since the part of C syntax people most often complain about is the declarations, which JavaScript of course doesn't have; I think the bits of C syntax JavaScript keeps are not so controversial...)
> Hopefully with people from the dynamic languages camp trying the language they'll clean up the syntax.
Considering the year elapsed, that's about as likely as them killing the project and admitting that Go is a turd which only gets airwave because it's a project by two extremely famous googlers. The syntax is crap, the type system is garbage, they spend their time reinventing utterly terrible wheels and they've thrown out basically all ideas of safety they could get on fire.
If IRC activity correlates to interest in the language, then data shows a bleak picture of interest in go-lang. Here is the total character count per day as a percentage of the activity on November 12, 2009.
http://i.imgur.com/8ERaf.png
X axis is days (approx) since 11/12/09
Y is % of chars as compared with the busiest day (11/12/09)
I've used the language for big projects and little projects. The strict error handling is fantastic. I like everything about the language except one thing. Just one, and it's a big nasty thing. I hope Russ, Rob, Iant or someone from the development team reads this, because it needs to be said, and others have said it, and it's the reason I stopped programming in go. Go might not need generics, the go development team might not need generics, but I DO! You wonder why there isn't a rocking go web framework? Because generics would be a huge help and no one wants to piece together a tedious solution immediately deprecated by the announcement we've been waiting a year for, "Go is getting generics!" All I want for christmas is generics ... and a pony.
Nah, the interest for new things from big companies always peaks shortly after the announcement. If you cut off the outliers e.g. before day 45 then this graph would look much rosier. Or, to put it another way, would the graph for any successful language like Python or C look any different in the first year after the initial announcement?
Those languages were all quite old and popular by the time those graphs started. It's not apples-to-apples to compare languages with a decade or more of use to a language whose inception was a year ago.
It may not be as beautiful as CoffeeScript (which we also use), as rich as Python, as safe as Rust, as concurrent as Erlang, or even as hackable as Ruby, but it certainly offers an unparalleled set of features which is hard to find in just one language — decent standard library, decent syntax, decent performance, super easy concurrency, a helpful and reasonably sized developer community, a relative level of stability, automatic memory management with good enough control over memory use, usable interoperability with C, native client support and even a standard testing framework.
Thank you and happy birthday to all the fellow Go developers out here on HN.