Hacker News new | past | comments | ask | show | jobs | submit login
Six years of Go (golang.org)
405 points by jaxondu on Nov 10, 2015 | hide | past | favorite | 317 comments



I have a bit of a love-hate relationship going on with Go.

On one hand, it addresses many of the pain points I've experienced with other languages. It's easy to build and deploy, reasonably performant, and has a powerful and consistent standard library.

On the other… developing in it feels like a total slog. It manages to be simultaneously far too anal and overly forgiving about syntax. Visibility definition using upper/lowercase is a shite idea. Package names (and packaging generally) are a mess. Magical built-in globals are a huge design smell. The lack of generics, as cliché a complaint as it is, results in loads of duplicated or generated code when building anything more complex than the simplest app. And so on.

I find the whole experience of using it to be unpleasant (rather like using a blunt knife), and yet it fits a set of requirements that mean I keep developing new projects using it – particularly high-performance small services that do things like fling JSON around, for which the built-in HTTP libraries + Gin are brilliant.

I'm looking forward to the point that a (trans|com)piler which smooths over the bad parts is available.


It's like most languages: if you go in hoping to write in the style of your favorite previous language, the language is going to resist you. Python does the same thing to you if you want to write in functional style. Ruby also punishes you if you want custom data structures (it's the Rails community that coined the term "golden path", right?). If you've got loads of duplicated code due to lack of generics, you may not be leaning as much on the design of the standard library as the language wants you to.

We've got a limit-order-book market with a FIX API and an HTTPS/JSON API, a bunch of market makers, an AVR emulator, a dispatcher to handle thousands of AVRs concurrently, a C compiler, HTTPS/JSON APIs to implement debug stubs for all of that, and a bunch of other random stuff --- and we have one (1) custom data structure --- the red-black tree we use for the order books themselves.

I'm a recovering C++ programmer and do not doubt for a moment that if Go had generics, I'd have availed myself of them. I'm not sure my code would be better for it, though.


Your code in Go almost certainly does use generics. Just not user defined ones. I don't particularly want to argue the generic point as I believe it is beat to death. But I could use a good concurrent map in Go in dozens if not hundreds of places.

I could use a lock free ring buffer in dozens of places. I could use promise/futures in dozens of places. I could use anything but the big honking lock that is channels in dozens of places.

I could use proper variance rules in the generics Go does provide in dozens of places. I could use monadic style errors and options in dozens of places.

Now, I agree that I generally don't need to write my own generic code very often, but if the blessed generic writers on the go lang compiler team don't write these things for me, I don't have a fall back option in Go (other than code gen, which people are starting to fall back on). It just seems unsustainable to me.


That's a fair point: the fact that Go seems to have a few hardcoded generics is one of the uglier bits of the language.

I don't think Go is a great language, as I'm fond of saying, I just think it's a very useful tool.


Been doing Go dev for over a year now, in a place where I can make the language decisions, so I clearly agree.

But it being a good tool should not be a deterrent from it becoming a better tool.

[edit] Edited to sound lest strident.


I don't disagree with your conclusion necessarily, especially given that I'm speaking from a position of ignorance with respect to Go, but I'm surprised by your statement about python and functional style. Coming from Ocaml, I found python to be one of the more accommodating languages in terms of maintaining the style I had built up in the former. (I do certainly acknowledge many examples for which this contradicts, immutability being a major point, but I can think of more situations where I was able to use similar design patterns than when I wasn't.) What in particular did you find lacking?

This all may be the ramblings of someone basing their opinions on "code I've written that has worked" and not on some higher standard of design patterns, so feel free to ignore if that's not productive :)

This ties into other thoughts I have rattling around about treating languages as specialty tools with well prescribed patterns, vs the trend to implement some subset of common lisp as the saying goes, but not well formulated enough to expound on them here. Broadly; I'm not sure which paradigm I prefer. (Having a big toolbox of specialty tools is nice, but if one tool can easily eat the functionality of another tool, I tend to side on considering that option.)


I agree to some extent; different languages require different coding styles – that's totally fine. But that doesn't mean that there aren't valuable features to be taken from other languages, nor that they the language's design doesn't have problems. I strongly feel we should resist the temptation to believe that just because an idiomatic design design exists means there is no room for the language to become even better!

I won't harp on about generics in Go, because I think it's far from the biggest issue – but the hardcoded magic generics show that such a feature is useful. I'd love a simple set implementation, for example – but I often find myself reduced to writing dumb, ugly, difficult-to-read code to work around the fact that it's not possible.

SICP famously says "programs must be written for people to read, and only incidentally for machines to execute." And I can't help but feel, whenever I'm writing Go, that I'm spending far too much time telling the computer what to do – and nowhere near enough telling future developers what I wanted to do.


I'm in the same boat. Go's simplicity is initially refreshing, then a huge pain once you find yourself writing the same thing over and over again.

A good example is errors being values — which is a great idea. But then you realize every single function needs to be littered 1-10 cases of

  if err != nil {
    return nil, err
  }
It's an extremely common pattern. It's tiring to write, over and over. Tiring to refactor, too: If you change a signature (to add an error, or add another return value, for example), every error check has to be updated.

Unfortunately, Go doesn't offer any abstractions that might allow you to avoid such boilerplate. Functions that return errors cannot ever be chained, for example: If you have "func bar() (MyStruct, error)", you cannot do "foo(bar())". You must always assign the result to an intermediate variable. You could embed the error in the MyStruct struct instead, but that goes against Go's grain.

I find myself wishing for some magic macro that is smart enough to extract a value and return the error for me. Something like:

  try! value, err := bar()
...would expand to:

  value, err := bar()
  if err != nil {
    return
  }
I'm with you on upper/lower-case names. It results in schizophrenic-looking programs. Unless I'm writing a library, I tend to just export anything that isn't obviously an internal implementation detail, for consistency.

I'm also up in arms about ":=" assignment behaviour. I've run into several bugs caused by shadowing inside blocks. You have to be careful when refactoring so as not to cause shadowing issues; really, editors should have their syntax highlighting set to highlight ":=" in blinking bright yellow or something. It's so hard to miss.

It's also inconsistent with how you (or, at least, I) want it to behave. It will shadow existing variables by default if there is at least one new variable on the left-hand side, but that's the least conservative behaviour, and feels contrary to Go's strictness — a language, after all, that considers unused imports to be a compilation error. Recently I've started avoiding ":=" in favour of vars, just to avoid falling into that trap by accident.

To be fair, I love many aspects of Go: Compilation speed, relative performance, ease of concurrency, static strictness. But after working with Go for a while and being quite productive with it, I'm at the same time seriously pining for a better language to replace it.


I felt very much the same way about Go's error handling; that, coupled with straight-line synchronous-style socket programming, made me feel like I was writing the same dumb C code I did when I was a teenager in the mid-90s.

I've come to believe that slicker error handling is a bit of a false economy, at least compared to other "informal" languages like Java, Ruby, and Python (all bets are off if you want to compare Go to Haskell; I concede everything in advance there).

I feel like a lot of Java and (especially) Python/Ruby code is easier to read... until it matures enough to handle errors properly, at which point its just as crudded up. It's much easier to start sketching out code in Ruby and wrapping everything in blanket try/rescue blocks. But that code always breaks and always gets trickier before it's ready to ship.

Lots of people I've talked to have had the same experience coming off C, Ruby, and Python as I have: when the Go compiler stops spitting out errors, your program tends to work --- usually not perfectly, but still far better than a first-run Ruby or C program does!

Also, when people think about Go error handling compared to Ruby and Python, they rarely factor in the density of unit tests required for the Ruby and Python code.


I think history has absolutely shown that exceptions are not the best solution; they don't scale, as you point out. And I agree with Go that errors are values, and should be passed around as such.

Go basically tells us that errors are as really important — they should be in your face and handled by the caller. And then it goes ahead and makes it a second-class citizen that is really awfully laborious to work with. Why not make error-handling a first-class construct?

Most code needs to just pass the error on to the caller, for example. Go would benefit from an easy way to just "bounce" the error off to the caller. Something like my naive, hypothetical macro in my previous comment.

Some sum-type-based solution like Rust's Result enum would also have made the whole problem pretty much moot.


> Go basically tells us that errors are as really important — they should be in your face and handled by the caller. And then it goes ahead and makes it a second-class citizen that is really awfully laborious to work with. Why not make error-handling a first-class construct?

Not only that, it's very easy to just dump errors on the floor, which is why Golang needs tools like errcheck.

For an easy example of this in practice (os.Setenv returns an error): https://github.com/search?l=go&q=os.Setenv&type=Code&utf8=%E...


Wow, people do this? I did have an error go unnoticed recently, but it was like this:

  v1, err := doStuff()
  if err != nil {
    return
  }
  var v2 MyStruct
  if value != nil {
    v2, err = doMoreStuff(
      some_param,
      different_param,
      one_more_params)
  }
  // ... use v1 and v2
  err = doYetMoreStuff()
I didn't catch the orphan err because I absent-mindedly focused on the parameter list to doMoreStuff() and just didn't see it.

But I find it frustrating that Go will, on the one hand, angrily refuse to compile a program where a variable is unused, but on the other it will happily accept a program where a value is never used. Isn't that potentially as bad? I'd rather have it complain and force me to assign to _ if I really wanted to discard it.


> I think history has absolutely shown that exceptions are not the best solution;

Good point but exceptions or explicit handling (even with sum-type like in Rust) are not the only ways. There is also the crash-and restart way, Go has some with panic, Rust, Erlang is probably king here, can do it with OS processes as well. That of course, has to be handled well by the runtime, so either no shared memory so corruption doesn't spread arbitrarily throughout the application or provable compile time checking (like Rust).


> If you have "func bar() (MyStruct, error)", you cannot do "foo(bar())". You must always assign the result to an intermediate variable. You could embed the error in the MyStruct struct instead, but that goes against Go's grain.

Chaining does work, but obviously the function needs the same signature as the return values, which limits things since most APIs don't accept errors as input. But within your code you can structure it to get error values for things you know you will be chaining. Or create wrappers to make your types chainable.

http://play.golang.org/p/5LHXdJlfIM


> Or create wrappers to make your types chainable

It can't always be done. A generic wrapper only works for functions that return values. It would be nice to have a wrapper that can take any function, e.g. foo in:

  package main
  import "fmt"

  func foo(a ...interface{})interface{}{
    if len(a) == 0 {
      return nil
    } else if len(a) == 1 {
      return a[0]
    } else {
      return a
    }
  }

  func barbar() (a, b int) { return 1, 2 }
  func bar() (a int) { return 1 }
  func baz() { return }

  func main() {
    fmt.Println( foo(barbar()) ) // prints: [1, 2]
    fmt.Println( foo(bar()) )    // prints: 1
    fmt.Println( foo(baz()) )    // compile error: baz() used as value
  }
Instead of the compile error, it would be nice if foo accepted baz() as a argument, which would read the array length as 0 and here return nil.


I swear I tried that once, and that it didn't work. Thanks for educating me.

Still, having to let every function take an error parameter isn't really an option, generally.


Have you seen this blog post by Rob Pike?

https://blog.golang.org/errors-are-values


This is very worth reading – it does offer some insight into the design process. In practice, there's still a lot of boilerplate error handling, but treating errors as values does help.


If there a paradigm for handling multiple potential errors in a function?

I'm usually stuck using:

  reply, err := redis.Givemethevalue(key)

  if err != nil {
    return err
  }

  thing, err2 := postgres.getById(reply)

  if err2 != nil {
    return err2
  }


Yes:

  reply, err := redis.Givemethevalue(key)
  if err != nil {
    return err
  }

  thing, err := postgres.getById(reply)
  if err != nil {
    return err
  }
Go allows you to assign with := if at least one of the left-hand-side variables is new.


I tend to use structs like mini "dynamically" scoped namespaces for breaking up hairy tasks. Pattern looks like:

    struct fooer {
      x int
      blah string
      // ... more state
      err error
    }

    func Foo(x int) (string, error) {
      f := &fooer{x: x};
      defer f.cleanup()
      f.stepOne()
      f.stepTwo()
      f.stepThree()
      return f.blah, f.err
    }

    func (f *fooer) stepOne() {
      // ... do stuff and maybe set f.err
    }

    func (f *fooer) stepTwo() {
      if f.err != nil {
        return
      }
      // ... do stuff and maybe set f.err
    }

    func (f *fooer) stepThree() {
      if f.err != nil {
        return
      }
      // ... do stuff and maybe set f.err; set f.blah
    }

    func (f *fooer) cleanup() {
      // ...
    }
While this is initially a tad more verbose, it has some nice benefits. For one thing, you can easily fmt.Printf("%#v", f) to dump all the relevant state. However, it also tends to be more resilient to refactoring:

- No method signatures to patch up.

- Easier to non-local jump via return if you have some unusual control flow, etc.

- You can easily find all references to `f.err` to verify your error handling.

- The method names and step list take on a self-documenting quality.

Another key insight I had when learning to tolerate Go: It's ok to do throw away work. You don't need to abort instantly on failure, you can just make sure code paths handle zero values or other invalid states more robustly. For example, I sometimes add a function like:

    func (f *fooer) fail(err error) {
        if f.err == nil {
            f.err = err
        }
    }
And then just add sprinkle some f.fail() calls, make code handle nils, invalid states, etc, and make cleanup code idempotent. Seems to work out much more nicely than if err, return.


I use

  var err error
at the beginning of the function if needed.


This helps prevent variable shadowing when using :=, which is yet another weird feature of the language...

BTW, if you really want to make sure you don't make mistakes, use the compiler tools, or, better yet, https://github.com/alecthomas/gometalinter .


It's odd, they've written that they were influenced by Pascal, which is where the operator " := " comes from. But it doesn't work quite right in golang...

In Pascal you would use := every time you wanted to assign a variable, and a single equals when testing, such as "if (x = 5) then...". It is slightly more like math than most languages, which I appreciated. But, golang only allows it on the first assignment, the reasoning perhaps that it is a declaration?

I don't feel that this third way of doing it with no advantage was a benefit, choosing one C of Pascal rules would have been better and less to think about.


I'm not an expert in Go, but can't you inline a statement before the conditional?

  value, err := bar(); err {
    // there was an error
  }
I like how that looks, personally. Obviously YMMV.


Actually, that wasn't really the point of my paste. But since you ask: Nearly. You can do this:

  if value, err := bar(); err != nil {
    return err
  }
Note that this syntax declares "value" in the "if" scope. You can only access it inside the "then" block or in an "else" block:

  if value, err := bar(); err != nil {
    return err
  } else {
    log.Print(value)  // this compiles
  }
  log.Print(value)  // does not compile
So if you need it later, you have to do:

  var value MyType
  var err error
  if value, err = bar(); err != nil {
    return err
  }
Note that you cannot do this:

  var value MyType
  if value, err := bar(); err != nil {
    return err
  }
This would, again, declare a new "value" that shadows the outer "value" inside the "if" scope. (Go would fail to compile it since it doesn't allow unused variables.)


It does look better, but `value` will only be accessible inside the block. That's a no-go if you want to perform actions with `value` below.


That is iff you use the shorthand declaration-assign: https://play.golang.org/p/6uGmPZIu4S


Correct, which is what the parent was asking about. :)


I agree, but i create Fatal and not fatal functions.

func checkErrPanic(err error) { if err != nil { panic(err) } }

func checkErrNonFatal(err error) { if err != nil { fmt.Println(err) return } }


> particularly high-performance small services that do things like fling JSON around

:/ Their json system reflects and allocates like a mad-man. It's probably one of the slowest parts of the std library.


Yes, this is a good point (and I've hit this in the builtin XML unmarshalling too). I should point out I'm mostly looking at go in comparison with Ruby rather than the C, so the JSON implementation is still high-performance by that metric :)


Do you know of a faster JSON library? I've been struggling with this. My particular use case is that I don't want any fancy struct unmarshaling; I just want the equivalent of map[string]interface{}.


https://github.com/nicksardo/jsonpath can pull out parts of a JSON document without unmarshalling.


That's really neat, thanks (do you have any benchmarks comparing it to Go's JSON?), but doesn't cover my use case. I want all the values in a map-like API. I don't know anything about the shape of the contents, names of the keys, etc.


Which libraries have you looked at? https://github.com/pquerna/ffjson and https://github.com/benbjohnson/megajson claim to be faster


Looked at both. ffjson is a library that generates the marshaling/unmarshaling Go code for your structs, so it doesn't support my use case at all. megajson is abandonware ("This tool is unmaintained. Please use ffjson instead").

go-codec [1] is very good, and can do things like interning string keys to reduce allocation overhead, but it's not faster than encoding/json when working on plain maps.

[1] https://github.com/ugorji/go


CoffeeScript for Go? ;)


After using LiveScript I wished there was a transpiler for every language to get LiveScript syntax in there...


You really should check out vibed. It meets most of hte requirements of slinging JSON around, being easy to build and deploy, has a powerful and consistent library. And it's not terrible to work in: http://vibed.org


Agreed. All of Go's deficiencies are not deal breakers when it is so well suited to network services that shuffle data around. I wouldn't build lots of business logic in Go, but often I just need to proxy data from point A to point B with some data massaging.


I'm skeptical that "feels like a slog" has much to do with language features you complain about. Better IDE support would go a long way here.

Java can be terribly verbose at times and the culture often makes it worse, but it often doesn't feel like a slog in practice because errors are reported as you type, with quick fixes. Editor plugins for Go will tell you some of the errors, some of the time.


I'm not sure about that. I don't tend to use an IDE, but the Go plugins for Sublime seem to do a pretty good job of identifying unidiomatic code and errors even before saving, which is certainly a benefit. Gofmt is fabulous.

The slog seems to be in the frequent feeling of 'why do I have to do this – surely the computer should be doing it for me?'. This is mostly around things like list comprehension, where it feels like using stone-age tools. It sucks, because the development story around e.g. goroutines and channels is so elegant in comparison.


Perhaps you are not smart enough.


You either "get" Go or you don't. Which shouldn't be surprising given that it is a very opinionated language.

A diagnostic indicator is whether you gravitate towards things like Martini or Gin, which aren't idiomatic Go and seem designed to ease the pain of using Go for those who don't actually care for it much.


But it's possible to "get" Go and also disagree with its design decisions.


I see what you're saying, but I absolutely "get" what Go is doing – you're right that I don't care for the idiomatic approach that much!

I have enjoyed the gin API. In maybe 10 lines of code, I can build a fast HTTP service that can serve up a small single-page app. The same thing using e.g. Negroni feels like I'm writing more boilerplate for no apparent gain – and I'm a great opponent of writing boilerplate code.


Curious your opinion on what you would advise if not Martini or Gin?

I love martini (and lately gin) and definitely love and use go every day. What about these frameworks is not idiomatic go?

Is there another framework that is? Or you suggest just rolling your own using net/http by itself?

Cheers


Here's a great blog post by the author of Martini about why, after he had gained experience in Go, he came to realize that Martini isn't very idiomatic: https://codegangsta.io/blog/2014/05/19/my-thoughts-on-martin...

tl;dr - Martini doesn't have a strict, type-safe API. Overuse of reflection leads to a small performance loss but a much larger, much more important cognitive tax.


I remember awhile ago Martini used to have a large performance hit that Gin didn't. I think it had something to do with the url multiplexer, wouldn't be surprised if it's since been fixed but it was the reason I initially chose Gin when I first started writing Go.


> I think it had something to do with the url multiplexer

"Slow" in the case of a router/mux is entirely relative though. There's been this strange focus on routing speed/allocations, when its the smallest slice of your total request-to-response performance. Martini's router won't make your application noticeably slower than any other.


After a day of writing Go, I certainly gravitate towards martini and gin!


It was early 2013, when we adopted Go as a default language for all our server side (micro or not) services. Before that we had been using Java for some years. The reason for the move were few:

1) Ambivalence on Java roadmap, in my understanding (gradual build up, since after the Oracle's Sun acquisition). Even the earlier clean java docs, suffered from Oracle branding efforts. Downloading older versions were confusing via a long chain of navigation between sites.

2) Boredom after nearly a decade with Java programming.

3) Memory usage of Java in our conditions was much higher compared to other languages (C, C++, Go)

4) Not Java's problem, but whenever one thinks of hosting a HTTP service in Java, thinks of using a container (e.g. tomcat, jetty, Jboss etc.). Go seemed to have made making services very easy. Its possibly just a perception issue, but its there in my experience.

So we wanted to move, and Go looked stable at the time from all my HN readings. C was too bare bones(even string handling was a pain to me, after a gap), and even C++ would not have matched some of the things which Go has inbuilt. Few examples:

1) Json/XML parsing is the easiest with no work (or minimal) required, you can just have the field names capitalized (or use stereotypes) and it gets done, with a line of code.

2) Great HTTP client and server libraries, which make very easy to write your own standalone services, as well as write http crawlers. (I am quite excited that Go 1.6 will have HTTP/2 support for both, as per this birthday blog).

So, in nearly three years of usage, with largely no regrets[1]. It is what they say it is: a bare-bones, fast (both compile & run) and stable (hardly get any errors after you have coded stuff, one of the stablest programming paradigms in error handling, etc).

Thank you, Go team! Hoping to use it for many years, as default server side language.

[1] Some of the 3rd partly libraries, we use are still not ported over to Go. They have Java, C++/C versions.


>It was early 2013, when we adopted Go as a default language for all our server side (micro or not) services. (...) The reason for the move were few: 1) Ambivalence on Java roadmap

So, because there was some "ambivalence for the Java roadmap", a language with multiple implementations, a huge community (including open source), and so entrenched in the industry that will be there in 2100 too, you switched to a 3-4 year old language with tiny adoption compared to it (outside of echo chambers), an arbitrary roadmap as set by the core team which might involve anything coming the time for a 2.0 release, and whose majority of development depends on a handful of people Google pays their salaries?


Lets just put it this way, I bought onto the basic proposition which was offered, after having read Rob Pike's original blog introducing it, and having watched lots of Go team videos. Some points which also went into decision making:

1) I am not a functional language programmer. No disrespect, just stating fact, after having noticed a Lisp programmer having questioned my choice regarding "boredom". So languages like Lisp, etc were out, and had to look for a C like language.

2) My boredom with Java was also because of years of using, YMMV ofcourse. Also we were seeing issues in containers we hosted on, and that entire deployment paradigm seemed liked that of 2000s. As I said, in another reply, thankfully I had the luxury to choose, which is often missing in Enterprisey setups. And my co-programmers were also excited about it.

3) One thing which I forgot to mention in my parent comment is channels. It really appealed to me as a model, compared to the Barrier style of programming in Java's util.concurrent. We use that feature heavily in our now migrated Go services, and its ultra stable.

4) At the time of the switch, I wanted to move to a more bare-bones language, which is C-like. So did some benchmarks with C, C++ and Go. And Go was found to take a little more memory than C/C++, C was the least. But it was good enough. And as a successful validation of the move, I have been able to recently move to AWS compute instances from the standard instances (m3.large -> c3.xlarge to be precise). So we are getting more compute power, by paying roughly equal, because of lower memory requirements.

So I made due effort to find the right language, outside the "echo chambers" you see. And this "echo chamber" is also not so actually, honestly speaking, I learn a lot from guys like you on a regular basis :-)

edit: typo


If everyone thought this way, our realistic professional choices of languages would be C, C++, and Perl. The exact same things you're saying about Go were things people said about Java --- a language, by the way, with much more harrowing ownership issues than Go, which is an open-source project top-to-bottom.


Gah! I just noticed that I replied to the wrong comment; I meant that for the grandparent. Sorry!


What do you feel are the much more harrowing ownership issues? If you google 'goroutine leaking' you get a pile of convoluted stuff. I don't mean to language-war, if anything I find 'stuff proponents and detractors said about Java in its early days' eerily similar (and likely as overwrought) to the same said about Go now.


Google is locked in a multi-billion-dollar lawsuit over the ownership of trivial bits of Java code!


Hah, I completely misread 'ownership'!


Ha. I built my first company on Java back in 1996. It was a terrible decision. Very buggy, lots of BS from Sun & Oracle that was really more about Ellison and McNealy envying Bill Gates. Netscape made a similarly bad decision when they tried to create a pure Java version of the browser.

I'm sure Java is 10x better now, but I'm not convinced it will be here in 2100.


It will be, because there is now more Java running business processes than there is Cobol, and Cobol is surprisingly still with us.

Profitable code dies hard.


I don't think there's any 85 year old Cobol though. Most of the S&P 500 is less than 50. It's entirely conceivable the companies that embrace new technologies starting today will, within 50 years, extinguish or acquire most of the of the companies using technologies from 1995.


What ? Of all the languages Java is the most likeliest to be around in 2100.

It is the lingua de franca of enterprise software development. In every sense it is the modern day Fortran/Cobol.


Cobol was the modern day Cobol in 1995, and that was just 20 years ago. 85 years is a long time.


1995? Are you sure? I started studying maths and computer science in 1993 and Cobol was ever only mentioned as a remote curiosity. I remember Pascal, Perl and C/C++ were common.


Yes but it was still dominant in terms of actual code in production. I remember working at a consulting firm then and we had a ton of work in Cobol and JCL. Banks in particular but also telecom.

Client-server 4GLs were really starting to take off -- PowerBuilder, Visual Basic -- but those got washed away with the web.


Well, one of those guys who designed the language is Ken Thompson.

That says something about the language to me.

You have a point but they seem pretty happy with their choice.

I believe that happy developers are more important than the tech stack.


and whose majority of development depends on a handful of people Google pays their salaries

As opposed to the brilliant stewardship of Larry Ellison?


Well, still not a handful of people, but a huge endeavour, and with a published roadmap for 2 versions ahead.

Besides even if Larry said "kill it" tomorrow, Java would still survive -- so much that it's used in all kinds of enterprises.


I think even if Larry said "kill it" Go will also survive :-)


On the other had, Google could kill Go tomorrow...


I don't think it would immediately kill it. If Google abandoned Go then given it has only a few unique features it would likely fall in amongst the hundred other second-tier languages that are around today.

It is pretty inarguable that a large part of Go's success has been it's affiliation with Google.


How? Its an open source project: https://github.com/golang/go


Tons of open source projects faltered and died when they lost core contributors. The core will remain open source and available, and you might even see a few commits here and there, but that will be it.

Go for the most part is written by a small team of paid contributors -- it's not certain at all that if they went away, other people would step in their shoes.


Google represents what 95%+ of the committers ?

If you took those away not to mention the message it would send to everyone would be enough to put the language in a death spiral. Good luck convincing management to use a language that even Google abandoned.


FUD.

- Do all opensource projects require corporate sponsorship to be viable?

- Do Python, Ruby, even Rust have corporate backers that cannot widthdraw support?

- Does Java, being under the control of Oracle, present a better option?

- Many business are using VB, C# and F#, which Microsoft owns. F# especially could be abandoned, but it continues to find new use.

The Go code I write and compile today will continue to work for a significant period of time. If Google stopped paying the committers, this would not change - the language may not evolve, but this is a minor concern on a project of Go's popularity.

Some businesses still rely on COBOL and Fortran, but those are not exactly evolving either.


>FUD

We're talking about decisions to adopt a language, so FUD and especially "uncertainty" is a very important factor to consider. This is not 1999 and Microsoft badmouthing Linux.

>Do all opensource projects require corporate sponsorship to be viable?

Not all of them, but a lot of them do. Especially languages. Even something like OCamL needs Jane Street and that french university a lot.

Go is not setup as even a 50-50 internal/external community. While the long tail is, well, long, the majority of commits and all of the steering is from Google devs.

>Do Python, Ruby, even Rust have corporate backers that cannot widthdraw support?

Rust has Mozilla and lots of paid programmers (all the core team for one). Without it, it would have gone nowhere.

Python and Ruby had had corporate sponsorship themselves too, but they have been far more organic (grass-roots) open source communities than Go from the start.

>Many business are using VB, C# and F#, which Microsoft owns. F# especially could be abandoned, but it continues to find new use.

Devs/Teams using F# are extremely few and far between compared to any established language such as C#, Java, etc. We're talking probably 2 orders of magnitude or more.

>Some businesses still rely on COBOL and Fortran, but those are not exactly evolving either.

Fortran is still evolving actually. Also Fortran and COBOL have been always mostly based on commercial compilers -- not community efforts, because that's how stuff worked back in the day.

And it's not like people write green projects in COBOL -- they just rely on it because they have huge important codebases that are 40-50 years old.

That's not the case with Go.


> all the core team for one

Not all (Yehuda and me, Huon), although both of us have been paid by Mozilla at some point in the past.


It is not FUD. It is a factor to consider, especially if you are thinking of creating mission critical software. There is no doubt that Google has plenty of form in killing projects, some of which were quite popular and/or highly visible. After all what percentage of Google income/infrastructure depends on Go? I presume it is really, really tiny and could become a casualty in corporate politics.

I personally think it is highly unlikely that Google would kill Go, but I do think one has to consider the possibility before betting the farm.


If Java is still around in 2100 I weep for how little progress was made.


Cobol, Fortran and Lisp are still around.


What language has ever died after having been used by more than a handful of programmers?


Most of the memory safe systems programming languages that were steam rolled by UNIX and C's adoption.

dBase III derivatives.

4GL languages.


Just the good ones...


> a language with multiple implementations,

Yeah, where the owner is suing one of those multiple implementations, and playing silly buggers with J2EE certification. That really lends a fuckton of conifidence.


I guess if you can't see the future, why not make it interesting?


You left out the key reason cited:

"2) Boredom after nearly a decade with Java programming."


> 1) Json/XML parsing is the easiest with no work (or minimal) required, you can just have the field names capitalized (or use stereotypes) and it gets done, with a line of code.

Obligatory plug - if you're sick of writing out the struct definitions yourself, you can generate them from sample JSON: https://github.com/ChimeraCoder/gojson

This is especially useful when implementing REST servers/clients, because you can simply include an example JSON response which your tests use, and then use `go generate` to autogenerate the struct. Since they're both based on the same file, you don't have to worry about keeping them in sync - if there are any changes to the response structure, you only have to update it in one place.


I've used gojson several times and highly recommend it. Originally I'd planned to make the tool myself but found you'd already created precisely what I envisioned!

/me tips hat to you :)


That is cool! Thanks


You based a business decision to switch language on "boredom"?

What size team are you working with, that you were able to switch from Java to Go?


Best reason ever!

Just to push a counterpoint, I never understood those startups with foosball tables, sponsored beer, team workaholidays on tropical islands but god forbid the work itself is any fun.

If a technology choice makes people enjoy their work more, learn new things, help them think differently and thus get more creative, then isn't that a big plus? Sure, maybe it does not weigh up to whatever downsides there are, but it counts! The whole idea that "fun" isn't allowed to be an important argument in a business decision feels horribly outdated to me.


Voice of dissension here. I switched from:

* Mysql to MongoDB * PHP to Python * Javascript to Coffeescript

All because I was bored of the old tech.

and it made the site unmaintainable. I mostly blame the MongoDB and Coffeescript for that.

Now to be fair, I learned a ton and I am so glad for that experience, but I lost my website.


Do you really thing it's fair to blame a whole language for making your project unmaintainable, when you admit you were just learning it -- and you had come from PHP?


php is much maligned here on HN, but it doesn't mean that it automatically makes for a bad programmer.

Here's another exmaple for you: Over the years, the project I work on has used the following:

vb .NET C# .NET

WCF asp Webforms MVC2 MVC4

The result is a maintenance headache (it's not a nightmare, but we do have to pause every time we unexpectedly encounter VB!), and that's where we've been disciplined enough to stay within the MS/ASP stack. Had developers been allowed to really go off-piste then we no doubt would have even more choices, and as a result be even less maintainable.

Yes, you might not be attractive to a certain subset of programmers if you are seen to be not using a trendy new language or framework, but there's the other side that by often switching you are left with a long laundry list you need to satisfy when you're recruiting so they can maintain the older parts. We already don't require vb experience, and we expect that people can pick it up well enough to maintain it, but a side-project in "go" might seem fun now, but if it becomes part of the business then you might find that in 5 years you have to take a bad choice in recruiting because otherwise you're left without anyone who can maintain that application.


> but it doesn't mean that it automatically makes for a bad programmer.

I came to PHP late from proper languages circa 2008/2009ish been programming since I was a kid in the 80's, I've no great love for the language, it's purely a tool and once you ignore the rusty bits it's not a bad language for a lot of web stuff but I've never been concerned with purity/beauty for it's own sake I just care about what I can do in a language, these days I use PHP a lot on the web, Python for just about everything else (even my build system for automating browserify is in Python using Envoy) and I play with Go and such on the side.

All that and there is a lot of work in PHP clearing up after others (if you like those kinds of engineering problems which I do) which is also nice.


I dont blame a whole language. Again, it was mostly mongo and coffeescript. Python was the best thing about the project.


<quote>All because I was bored of the old tech. and it made the site unmaintainable. I mostly blame the MongoDB and Coffeescript for that.</quote> I think the blame would logically reside with you.


Thanks for reminding me.


MongoDB I can see, but Coffeescript is just sugar on top of Javascript, and I struggle to see how it could make any code unmaintainable – but i'd be interested to know why!


Oh, you switch to MongoDB if you are bored with your current job ;) Otherwise PostgreSQL is what you switch to.


What's the problem with document databases, really? To be honest, for 80% of the projects I've ever worked with, fixed-schema rdbms's fitted just like... a square peg in a round hole!

Heck, even for advanced analytics, I find mongo aggregates and mongo map reduce 10x more intuitive and SQL that inevitably ends up using zillions of non-portable tricks, stored procedures and god knows what. And atomicity and whatever else transactions guarantee you in theory can be easily emulated with some good db structure design tricks and app design tricks in practice.

And the smarter a RDBMS is, like Postgres, the more dangerous it becomes for maintainability: it's a zillion times easier to maintain 'logic expressed in app code' (because you have basic stuff like version control, tests and so on), than 'logic trapped in the db' (good luck explaining to a new developer how "X automagically happens because of trigger Y and stored procedure Z, so there is no app code for X that you can instantly tweak to change how it works"). This is why I at least have some respect for mysql: it's retarded enough that it forces you to put the login in the code, where it f belongs!

Really, give me a dumb document db like mongo any day! And if I want something "less dumb" there're things like arangodb and rethinkdb that can also do joins and graphs. And there're also "true graph-dbs" for index-less "joins"/traversals, like neo4j and orientdb, for when the relationships for when you actually end up doing more than 3 to 4 levels deep joins...

Imho the development of "high-end rdbms" like postgress and oracle has been a huge waste of human brainpower and all the benefits supposedly provided by these pieces of technology were actually from the clever app-level code that mostly worked around their inappropriateness...


I was not referring to document databases as a whole, just to MongoDB in particular. You can use PostgreSQL as a document database. I heard too many stories with Mongo where people were dealing with locks or broken data instead of solving their business problems.


Yeah odd choice in that Go is a very boring language (and its enthusiasts consider this a feature).


What's "boring" about it? I'd argue that the possibilities for crazy concurrency patterns make it exciting.


> You based a business decision to switch language on "boredom"?

Not just boredom but Java induced boredom. In case of Java boredom is symptom not the essence.


Good question. Small team of 2 developers, so I had that kind of luxury, which I am sure is not there when you have larger teams.


If he were honest, I'm sure the weights for each factor really look like this:

*

*

*

*

*

*

* *

* * * *

* * * * * *

(2) (1) (3) (4) (5) (all others)


4) is actually quite important. People wonder why PHP is so popular, and it's because the deployment overhead is tiny compared to, say, Tomcat. Especially on shared hosting.


Thanks for your comment! Thanks Go team !


honestly I have hard time comparing go to java and finding any valuable reason to switch from one to another.

Go in my opinion was not mean for writing large/distributed web applications. But instead for writing tools (and fits very nicely in that space) and therefore replace C code base.

If I had to write something like docker, go of course would be a natural choice for it. But If I had to write the next big social network, well Java would be the natural choice.

Java has a much larger community, libraries, tools, ide and a whole ecosystem that makes Java and JVM a solid platform for writing application at scale (large team, large code base).


MAYBE. But maybe not: what if your app has a Javascript based rich client, and the back end is primarily micro-services? Does Java still shine for that kind of a stack? (OK, I would still avoid C, but that's not saying much)


I wish the gdb support were better or that delve were more stable. I also had some weirdnesses using cgo on osx. Then I went into #go-nuts on freenode, and I got told I was wrong and there was no problem.

Back in 2009 #go-nuts seemed to be a much different place.

I write Go at work, and I admire many of the same things in Go I admire about Python.

I still wish generics were part of the language and will say their excuses about not being able to do it in a performant way seem to just be away of avoiding the subject.

Ocaml for instance, has a performant generics implementation.

Sometimes the Go community can have an anti-programming language research and anti-intellectual feeling which can be annoying, since in addition to Go I write a good amount of Haskell.

The tooling is nice as people say, however I think more maturing of the platform needs to be done. It's also never talked about how much slower Go's claim to fame of fast compilation got much slower after the 1.3-1.4 switch to a compiler totally in Go. In all fairness, I could be wrong about the last one since I haven't benchmarked it... but I can say it feels much slower than it was around 1.1/1.2.

Concurrency in Go is easy, however I feel like many erroneously think that channels or concurrency primitives like it only exist in Go. There are other languages with rich concurrency and parallelism options as well.

Using lots of interfaces and casting everywhere gets on my nerves since I like to have the strongest guarantees possible via static typing.

Overall though, I can't say I've had a bad experience with Go. I can say it feels like I'm using an okay tool (great in some places) with maintainers who put their hands over their ears to potential improvements (see the generics proposals over the years).


What I don't understand is the people who say Go doesn't need generics. Go already has generics: channels, maps, make(), len(), range, etc. are all generic.

Nobody can argue that generics in Go isn't extremely useful. After all, you couldn't have typed channels without generics. One has to be pretty obtuse to argue that the utility afforded by Go's internal generics wouldn't extend to the language as a whole; that somehow Go's standard library needs to be special.

If you look at the standard library, its authors had to jump through some serious hoops in many cases. Packages like "reflect" (the megatype Value), "builtin" and "sort", to pick a few, are a graveyard of typing awkwardness. The sort package and its special function just for sorting strings is practically a written confession.

Generics being a speedbump is an argument I haven't heard before. Can anyone comment on what the performance challenge is? Nim instantiates unique concrete type instances based on their parameters, couldn't Go do the same?



It's extremely incomplete. They enumerate some challenges, but don't investigate languages where generics is apparently a solved problem. Whole sections are blank, especially — and perhaps revealingly — the ones that are about less C-like languages such as Haskell and OCaml.

I wonder how the situation compares to Swift, Rust and Nim, three recent languages that have managed to implement generics without (as far as I know) a single complaint, and without descending into C++ madness.


I've been yelled at on #go-nuts too; I ran into what turned out to be an authentic limitation of Go's I/O scheduling, and was instead chided for _'ing out error results in my minimized example code.


It's really a shame when a community's most visible public channel devolves into "you're doing it wrong"-itude. When I first started looking at Go in 2010 or so, coming from the rails community, I thought it was wonderful how friendly and helpful #go-nuts was. Unfortunately, it seems like an inevitable result of the regulars in a room seeing a deluge of similar questions and increasingly losing their patience. Eventually, everything starts to look like an instance of some annoying newbie pattern with a pat answer, and you have to fight to convince people that there is something novel and non-pat going on.


Yeah I have been bitten by the _'ing errors thing in the go community.


Given other aspects of Go's design, I'm actually a little surprised that Go makes it as easy to drop errors on the floor as it does. It feels like the language's strict checking of unneeded or missing imports and its lack of checking for capture of return values are philosophically at odds.


If compiler did it, how else would they get to chide people in people on bad style ;-)

But yes, good point. I think a better type system should handle it and make it harder to drop errors on the floor. But that kind of asks for Rust's like sum-type which is too close to generics for their comfort.


What was the limitation?


Very fast port scanner with fine-grained timers, the I/O scheduler leaks file descriptors (briefly, but enough to be a drag).

I got around it by coding down to syscalls and allocating a goroutine to a simple poll() loop.


Go's concurrency is limited to the CSP-style and favors share nothing problems. Languages like Clojure can do CSP just fine, but also have powerful language-level support for heterogeneous concurrency problems that are easy to use and easy to understand.


This isn't remotely true.

CSP via goroutines and channels is idiomatic Go, but it's not the only option. Go offers mutexes and other concurrency primitives which, along with goroutines as lightweight thread analogues, allow what you're looking for.


The real problem here is that Go does not allow a user to create their own powerful concurrency primitives.

Locks exist, but you can't create a synchronized data structure. You can't create your own channel type because that's a generic thing which is reserved for the language authors, not the language users.

The whole point of modern programming is to create useful abstractions that allow a programmer to get things done without having to worry as much, and concurrency-related abstractions like parallel map-reduce and actors are powerful, but you have zero chance of making an abstraction for that in Go.

In Go it's basically CSP or bust; saying "you can use locks" is not an answer; locks are not a way to handle concurrency, they're a primitive for shooting yourself in the foot if you're unfortunate to be in a language where you can't abstract them away suitably.


I'm not sure what stops someone from creating their own channel types.

type MyChannelType chan MyStruct ?


I wish I could upvote this +1000


.. mutexes limit you to the locking paradigm. You know there's more/better out there, right? If you want an actor / agent model you still must do this with mutexes channels and goroutines, resulting in some pretty fugly code, more so than normal go code.


`#go-nuts` is a very angry place.


I tried to go there to ask some questions while picking up the language, and what I got was RTFM, where manual includes the language specification, Effective Go book, and A Tour of Go. Apparently you're unfit to ask a question unless you know everything about the language already. Killed my excitement for learning the language.


What languages have nice IRCs? I ask b/c I was very pleasantly surprised by the extremely civil and noob-helpful #haskell.

Are there other nice ones out there? Good to know...


#elixir-lang is quite nice and noob friendly too.


Yep, check out #rust on irc.mozilla.org


Sounds like a sadly universal experience. It's really unfortunate — Go is an interesting language, but the place they tell beginners to go to interact with the community is so utterly toxic to anyone who wants to ask any kind of question.


I've never used Go before, so I went to the project's home page. There's an editing window on the home page with a sample program showing, and a few other programs available in a drop down list. I couldn't help but start playing with the language.

I wonder how much the simple presence of an editing window on a language's home page contributes to overall adoption of the language. It sure lowers the bar to "I'll just write a few lines of code and see how this language feels."


Rust has a similar feature on its homepage: https://www.rust-lang.org

Let's hope this becomes a trend!


Does anyone know how it works? Like does it make requests to a service or is it running in the browser, JS style?


There's a section called A Tour of Go [0] which has a series of code samples with explanations. The last part of the introduction to the tour says a little about what they call the Go playground [1]:

"This tour is built atop the Go Playground, a web service that runs on golang.org's servers.

The service receives a Go program, compiles, links, and runs the program inside a sandbox, then returns the output."

[0] - https://tour.golang.org/welcome/1 [1] - https://tour.golang.org/welcome/4


It's the same stuff that powers the playground: http://play.golang.org/

More info here: http://blog.golang.org/playground


It makes requests to a backend service. You can read more about the implementation of the Go Playground on the blog[0].

[0]: https://blog.golang.org/playground


I've been working on a huge monolithic project (for 1 person) for the better part of 2 years now. It is in PHP, but the backend segments ported over to various other languages like python, javascript(nodejs), and now to Go.

Having now developed 30 micro-services for Go, which all utilise channels and thus run much faster than any other language I used is just amazing.

Not only has my productivity increased majorly, but also my support time has rapidly decreased.

These micro-services which run in the background just work:

- With PHP they don't run out of memory or the database connection doesn't time out.

- With Python I don't get random crashes due to pool.map.

- With NodeJS I don't have to run multiple instances to get the speed.

I've looked at web frameworks like beego, gin, revel and others. But I'm waiting till something comes out that's more inline with what I have used with PHP. Something like slim framework.

If it ever does come out, it will give me the push to switch 100% to Go. Can't wait really.


I tried gin, martini and revel and found myself reaching to go back to largely the stdlib after about 6 months of development.

The stdlib with a couple convience functions really is quite good.


Me too. I found that most frameworks actually get in a way instead of helping. stdlib FTW


> Having now developed 30 micro-services for Go, which all utilise channels and thus run much faster than any other language I used is just amazing.

Any public code examples ?



I love Go. It helped me so much, not only career wise but also on a more personal level, bringing back the excitement in programming I missed so dearly from my early days. Drop by at one of our Golang meetups if you're in the Munich area. http://www.meetup.com/Munich-Gophers-Go-User-Group/


Congrats to the team. Go has never let me down in my work and my personal projects, it's just awesome.


Go seems like a fun language that has been sitting on my "look into it list" for a while, can't belive it's already six years old.

Since the TensorFlow video post is currently on the frontpage as well...as someone who uses neither C++ nor Go (I can write FizzBuzz level of code in both and read both well enough to get what's going on) I have to wonder how much internal buyin Go really has at Google if the core of such a project is implemented in C++. It's a project they see as valuable in the future and it would lend itself really well to Go as these calculations are done distributed and yet they picked C++.

[I'm not sure how much of the old framework they reused but if the will to Go was really strong I'm sure that wouldn't have been an issue]


It's a project they see as valuable in the future and it would lend itself really well to Go as these calculations are done distributed and yet they picked C++.

Go is not Erlang. Go supports green threads (goroutines) and offers CSP-like channels to communicate between threads. However, it does not have a distributed computing story yet (at least, not compared to Erlang, the usual Java frameworks, etc.).

For a library such as TensorFlow, Go is not really an option yet, for many difference reasons. E.g. the lack of parametric polymorphism makes it hard to parametrize code for single, double, or even half precision. Go does not support anything like expression templates, which exploit laziness to eliminate temporaries. Moreover, a lot of machine learning happens on GPUs nowadays. AFAIK, there are no CuDNN bindings for Go yet.

tl;dr: impedance mismatch


> Go supports green threads (goroutines)

As far as I know, goroutines are NOT green threads (threads managed by run-time environment instead of OS). Go produces native code (no VM). And, the goroutines can be multiplexed (depending on implementation) to OS level threads.


> Go produces native code (no VM)

Green threads can be managed by a runtime library or VM, so no VM doesn't mean no green threads.

> the goroutines can be multiplexed (depending on implementation) to OS level threads.

Being multiplexed onto OS level threads is normal for green threads. Goroutines are "hybrid" (M:N) rather than "user-level" (N:1) threads, but anything other than 1:1 native threading means that you need a runtime or VM managing it, and its a kind of green threads.


I see. So goroutines are just green threads with a nicer name? Thanks for correcting me. EDIT: Editing my comment because I can't reply to your reply. Yeah, I used "just" with the intention of saying that goroutines are well within the category/definition of green threads.


> So goroutines are just green threads with a nicer name?

I don't know that I'd say "just": like Erlang processes, goroutines have some special features not shared by all other green threads, even with a similar M:N threading model. I'd say that Erlang processes and goroutines are each specific kinds of M:N green threads with unique features and distinct names. So, its useful to distinguish them within the broader category, they just shouldn't be distinguished from the category.


I think in the TensorFlow case it is just a purely technical decision - I don't see how they could achieve what they aim for with that project in Go (or really, in anything but C/C++ at this point in time). Right tool for the job, etc.


+1 for right tool for the job. Also, I can imagine they have large amount code already there in C/C++ since this is the second deep learning system they designed.

and if you watch Jeff Dean's video, he mentioned more front end in other languages, Go is the only example and as the interest from internal.


Go is a language designed by Google people, but it is very much not the standard Google language. Most things Google does aren't done in Go.


Having said that Rob Pike told me that Go is now one of Google's "official languages".


... which just means developers at Go now have permission to use it, along with Python, Java, and C++, to build things, right?


I believe so.


Not so much permission as support. Being an official language means that the core internal libraries have Go bindings.


what does "just" mean?

What are your company's official languages used for?


Pretty much.


It is a standard language at google. It gets used for things like the download service and other high throughput service which is it's sweet spot. The TensorFlow project in previous iterations predates Go's official stamp of aproval at Google I believe and stopping to rewrite is an unnecessary step. It's possible that now something like Go would be used instead.

[Former Googler around when Go got it's start]


Go is a great language. Building REST servers in Go is a doddle and the related tools have obviously been designed to work well together from the outset which is unusual.

That said, I started learning D at about the same time as Go, and for some reason D has attracted me more. Possibly the C ABI compliance (I was doing some JNI work at the time).

One question that I haven't found the answer to yet though is how well Go apps perform for long running processes, eg weeks or months? Have there been any issues around memory usage or resource handling? Any need for restarts?


Go websites are essentially long running processes. I have several websites built in Go, all of them running for about 2 months already with no hiccups.


I can echo this. Have some go processes that have currently been running for over 6 months.


I have been running multiple instances of the same Go app on multiple servers without it ever crashing for about a year. The current uptime (since the last release) is about 4 months, no issues at all, and very low resource usage.


I picked up the new Go book (gopl.io) and have had a lot of fun going through it. The prevailing feeling of Go is "getting things done".

I also write a little Go program every day as practice. If you want a sample of some Go. https://github.com/kris-s/daily-go


> The prevailing feeling of Go is "getting things done".

This is a common refrain amongst go proponents and I find it quite distasteful. It either implies those of us who prefer other languages aren't "getting things done" or those who feel productive in Go aren't smart/hard-working/educated/etc enough to "get things done" in other languages. I don't think either is true.

I think a more accurate way to look at Go is that the language, tools, and standard library make decent design trade-offs when your target software is 1) simple 2) network daemon-y or a CLI and 3) going to be worked on by a wide variety of developers. There are lots of problems that fall into that problem set, and it is very nice to have a language targeted at it, but Go is certainly not a good fit for a huge number of software projects. You will be less productive in those cases using it.


I agree with you, but there is something to the argument; it's just poorly phrased as "getting things done".

gofmt, for instance, is uncontroversial. Taking the decisions about how to format code away from developers and standardizing it is widely seen as a win (a win Python flirts with as well).

Well, there's a lot of other things in Go that have been pre-decided for you, not just the formatting. The net effect is that you don't have to waste time:

* thinking about designing a DSL for your programming problem (DSLs in Go require parsers)

* designing a class hierarchy to express your programming problem

* choosing between event-loops and callbacks or pools of threads

* picking the right associative container library (do I want a red-black tree? a hash table? a trie?) for routine coding problems

These pre-decisions can feel confining, but I think for a lot of developers Go reveals that those decisions were usually a waste of time. When you actually hit a place where you need a red-black tree, it's not that big of a deal in Go to bring one in. You're just not going to do that for your session store or for a simple lookup cache --- which is, I think, what a lot of people who can't stand Go's lack of generics would be doing.


I think that falls into my use case of "simple". If you don't need to make those kinds of decisions, then by definition your problem set is simple (at least from a business logic point of view, even simple business problems get complex at scale).

The problem, I have with the sentiment (which I grant is largely me over reading into it) is that a lot of the things people think of as noodling or a waste of time, are the central problems in more complex environments. Making sure your program is correct is very important in some environments. Making it easy to express complex domain knowledge as a subset of a programming language is a huge win in some environments.

That isn't a lack of getting things done, thats just more complex logic requirements.


I think you're missing a subtlety of my argument. I'm not saying you never need to pick a container that isn't a simple hash table, or design a DSL, or roll your own event loop, or design a hierarchy of abstractions. I've done all of those things in Golang --- even the event loop!

But in C++, those are decisions you might make in parsing a config file, or in managing a simple table of sessions, or adding an LRU cache to something. You can't get away from the decisions. I have an array of stuff, and I have to decide, "do I want a list, an slist, a vector, or a deque, and what the fuck is a deque?". 98% of the time there is one sane decision that is so close to optimal that it's not worth tinkering with.

In Go, for prosaic, routine code, those decisions have been made for you. You have to go just annoyingly enough out of your way to second-guess those decisions that you almost never do, and you're almost always better off for not having to do it.


> You can't get away from the decisions. I have an array of stuff, and I have to decide, "do I want a list, an slist, a vector, or a deque, and what the fuck is a deque?". 98% of the time there is one sane decision that is so close to optimal that it's not worth tinkering with.

I'm currently working on a project (WebRender) in which we keep using the standard library hash table in the first cut of code whenever we need an associative lookup table, and every time we use it it keeps coming up #1 in the profile. Almost every single time. We then have to switch to another, more optimized data structure, and generics really help here so that we can reuse these data structures. In fact, if we didn't have them, we'd probably be sunk.


Again, I'm not arguing that we never need custom containers.


I'm saying that some projects need custom containers all the time—to the exclusion of the built-in ones—and need to reuse the implementations of those containers.


So did we! We didn't use Golang's maps to implement limit order books; we used a red-black tree. We did not build our own, nor did we find a red-black tree that was designed for order books.

This just isn't as much of a big deal as people think it is. Go makes it a drag to use a custom container, but it doesn't make it hard, and that might be how it should be!


And you had one data type that you used with that red-black tree, so you didn't mind not being able to abstract over the types of objects you were placing in the container. But we have lots of data types that we reuse for freelists and other types of containers. We don't want to have to reimplement that code for every single type we want. That's where generics save us.

> This just isn't as much of a big deal as people think it is. Go makes it a drag to use a custom container, but it doesn't make it hard, and that might be how it should be!

I believe you that it wasn't a big deal in your case. But I disagree with your general claim. I think you're extrapolating from your use case to claim that generics aren't important (vital, in some cases). I'm saying that, in my use case, they are.


I sum this phenomenon up as "frictionless development". I don't have to stop and make a decision about something not core to the problem I'm working on while writing code.

If the default doesn't work for some reason then I can tackle that problem but at that point it usually is core to the problem I'm working on.

For some people Go is anything but frictionless though. They spend all their time in Go fuming that their favorite abstraction isn't there. For those people my experience doesn't translate.


Not a big fan of gofmt, but oh well. (I prefer more whitespace, both spaces and newlines, than K&R formatting would like)

Otherwise, the go built-ins are usually the "get on with it" win.


It's true though. Go has a small number of language features, and they are only the simplest ones. It can be learned in a day. Other languages like JS, Ruby, and Python have a big fixation on figuring out the prettiest syntax for stuff (JS promises and chaining etc, "Pythonicness", and Ruby's incessant cuteness). In Go, you can't really make things pretty, so you just bang out code.


I don't know that "pretty" is the right description. High quality, well made, canonical C has a certain beauty to it and Go tends to offer a degree more on that vein. I personally find that much of the js, Python, and ruby "beautifying" is related to compactness more than being easy for the next guy to view the correctness of or understand.

It's subjective though. I'd guess that if you're a fan of the suckless style of engineering, go might be right in your wheelhouse and you will probably find it very beautiful if you can accept garbage collection.


>> It can be learned in a day.

The syntax perhaps. In reality there are a large number of concepts and idioms to learn on the never-ending road to really becoming proficient.


Yes, but there's a kernel of truth there. I wouldn't say I managed to learn Go in a day, but after perhaps six months using it I was much closer to mastering Go than to mastering other languages I'd been using for years. Go's road to proficiency is a shorter one, there's just less stuff to cover.

Take initialization for example: look at all the edge cases belabored in section 8.5 of the C++14 spec, or even the intricacies of initialization in a simpler language like Python. Now contrast this with how much lexical and conceptual space it takes to describe zero initialization in Go's spec: https://golang.org/ref/spec#The_zero_value

As in other areas, Go's approach here has downsides. (Possibly major ones.) But those tend to be conscious design decisions to minimize the total number of concepts and idioms present in the language.


Promises (which aren't limited to JS) are about far more than pretty syntax. Promises and promise combinators give you guarantees about your code, such as "no promise will ever execute both its success and failure callbacks" and "of the callback that is executed, it will never be executed more than once," and "once a promise is resolved, it's state cannot ever change."

Also, I don't understand the benefit of being able to learn a language in one day. You can learn how promises work in a single day and then apply that to any language that implements them. With Go, you will learn the language but then have to re-implement promises for every type that you have [0].

Consider the use case of issuing two API requests concurrently and assembling their results. You can do this using the fan-out, fan-in pattern described at http://blog.golang.org/pipelines

Search the page for "func merge". Any time you want to fan out and fan in, you will have to write that block of code for the types of the channels you have, or else use interface{} and lose type safety. So the cost of a language that can be learned in one day is that every single time you perform this very common concurrency pattern, you will have to repeat this code and potentially make errors in the process. And if you want to change how this merge pattern works across your codebase, you will have to change it in many places. What happened to DRY and reusability?

[0] There is a Go promises library, but it uses interface{} for all callbacks and does not appear to have been an active project over the past year. https://github.com/fanliao/go-promise


>Other languages like JS, Ruby, and Python have a big fixation on figuring out the prettiest syntax for stuff (JS promises and chaining etc, "Pythonicness", and Ruby's incessant cuteness). In Go, you can't really make things pretty, so you just bang out code.

So, just like VB then?


Or .bat file master race.


"Ruby's incessant cuteness" is a first class feature of the language in practical environments, but not of the language itself, in my opinion. While I can knock python for whitespace, and not a whole lot else, I think ruby is probably the most "learn in a day" language I've ever experienced. Without any background in strongly typed language or anything else C-like, Golang actually took me several days of work just to understand paradigms like slices, which were pretty foreign to someone who only worked in dynamically typed language.

JS is pretty damn tricky though, I'll give you that one.


I think a difference here is not that people don't get things done with other languages, it's that the language was designed with that as a first class metaphor. (Whether or not that is true I can't say, but that's the feeling the poster gets.)


You are over analyzing that phrase.


Granted.


> This is a common refrain amongst go proponents and I find it quite distasteful. It either implies those of us who prefer other languages aren't "getting things done" or those who feel productive in Go aren't smart/hard-working/educated/etc enough to "get things done" in other languages. I don't think either is true.

It could just be the feeling that Go gets out of your way more than other languages do. (For example, people complain about how much ceremony is involved in writing Java. Go could easily feel like "getting things done" in contrast.)


"Getting things done" is quite accurate considering large number of popular Go projects in short time compared to allegedly better design languages ( Scala, Rust, Haskell, D, OCaml etc..)


You are mixing productivity (getting things done), quality (better designed languages) and popularity (large number of projects) in the same sentence, but you generally cannot find causal links among them.


In Haskell a lot of it is due to people thinking they need to deeply understand everything before cranking out code. It's like trying to understand music theory before strumming some guitar strings... actually it's probably something less useful than that.

However, I guess the inability to deeply understand or pontificate about Go is an advantage in itself... forcing your only potential activity to be getting work done.

Also, are you sure that there are more popular Go projects than popular Scala projects?


That may also have to do with the massive push behind it.


that would mean javascript is better than go for GTD ;)


I recently implemented a RESTful resource mapper in go, which just accepts some basic parameters and an exemplar of a storable structure and wires up all the HTTP endpoints necessary to give users CRUD access to the resource.

I'm honestly very happy with how straightforward it was, even lacking generics---I solved the problem of no generics by basing the resource creation and management on JSON and a "Storable" interface that just defines key() and newEmpty() methods (so I have to write five lines of boilerplate for every struct that will be a resource... shrug). I didn't parameterize the storage logic, basing it on only a single NoSQL backend (BoltDB); however, parameterizing that side shouldn't be harder than wrapping the database access behind another interface.

I like the ability to switch between tight static typechecking and freer runtime typechecking on-the-fly, without having to build a large, complicated framework for either within the language. It may not be the most innovative language of the decade, but I think it's a pretty good combination of features for practical, high-performance web server development.


Would you care to share some code example?


Happy to; I'll share the whole thing.

http://pastebin.com/qBh6NRXc

It's not cleaned up for easy reading (hell, I haven't even run `go fmt` on it ;) ). But it has unit tests and seems to work. ;)

One thing worth noting is that it relies on the Storables to also be tagged with necessary JSON. It occurs to me that I could also have used tags instead of the key() function in the interface to specify which field in the Storable should be the resource name; key() is a bit more flexible in that the function could calculate the name using any method though.


Just for you, I did a code review. The code review has two revisions, one where I gofmt'd it because I can't read non-go-fmt'd code anymore, and a second where I added comments expressing some concerns. I'll be honest, I gave up on a few bits just because it wasn't fun to do; I strongly suggest rethinking the use of a storable interface vs taking an 'interface{}' value for both gets and puts akin to how the json stdlib does it.

You can see the comments here: https://gist.github.com/TheDong/ce1d7b86b88c86d972b6/revisio...

You should never post code without a copyright license or disclaimer attached and I'd appreciate if you rectified that forthwith.


Thanks for the review! I appreciate the feedback. One key piece that might have been unclear: since this code is part of a larger module (note package main), some of its parts live elsewhere. If I were to publish this, I'd consolidate those parts and build some proper module isolation here. OnStore is there purely because one of my resources needs to notify another part of the program that it has been stored; if I ever clean this up for public consumption, I'd probably want to add both pre- and post-handler hooks (along with the ability to add more rules and change the defaults, as Angular's $resource gives the client).

The advantage to the Storable is that other parts of the program can create and store those resources without needing knowledge of how keys are constructed. I also can't think of a way to do what empty() does without making it an interface function; "I need another copy of this unknown interface type" isn't something go has a clear solution for. Hypothetically, I could make empty() into a function that returns interface{}, take the key() suggestions you've given (though that leaks key-making knowledge), and then the whole thing would operate on interface{} type... Doable and more flexible, but not quite as clear on what resource will actually be stored and retrieved. Good tradeoffs.

A bit of feedback on feedback: avoid adjectives like "dumb" and "stupid." The signal-to-noise ratio is too low on them, and it makes for a harsher community (as other commenters in this topic have mentioned on their experiences trying to get help).


Thanks you, Go team!

Have been using Go for the last few years, from backend, tools, and even complex scripting type of tasks (for things more than I would like to do in Bash). Start using Go for game development as sideline projects recently, it is fun.

Granted there are things I would like to see may not on the road map, but I am very happy with what we have now, the great tools, and the great community.

Keep up good work and looking forward to the future releases!


I tried Goland for two of my personal projects. Initially I thought I will get used to the new syntax, but it never happened. It may have certain performance-edge over other languages but I wouldn't call it a modern language. I find coding in C more fun than Golang..


I picked up Go because C frustrated me so much. Can you give some examples as to why you prefer C?


Not the author...

I prefer C99. A smattering of features I like:

  * Variable Length Arrays
  * Variadic Macros
  * Designated Initializers
  * Anonymous Structs
  * Compound Literals
Some of the meta-"features" I like:

  * No built-in runtime or GC
  * A choice of dynamic vs static compilation
  * A good libc is wonderful but not necessary to get work done fast
  * The tooling is mature and plentiful
I'm sure Go is a fine language. I probably suffer from some sort of first-language bias as I've been using C for a long time and only know a smattering of Go from toy programs, blog posts, and reading the source to interesting projects like CockroachDB.


I just want to point out:

1. Variable Length Arrays: Go has slices 2. Anonymous Structs: Go has these 3. No built-in runtime (in C): This is not true unless you are compiling -ffreestanding -nostdlib, etc. I have done this in C, but such programs have to call system-calls directly and provide their own malloc, etc.


Not for every project but it does have it's uses (re: -ffreestanding -nostdlib, etc)


It's probably not at the point yet where you'd be interested in it (especially for tooling), but you might like Rust in the future.


Started using Go for my latest project (a successor to Evernote). It feels like such a relief, especially having just come out of a node.js project. It's everything I wanted in a (web-app) programming language, and for the first time I can say that a language has actually made my code better. I've never had a codebase this clean before.


I don't mean to be snarky and I'm definitely showing my age here, but isn't that exactly what devs were saying about node.js two years ago?


Perhaps it's because what makes a codebase messy is having written code in it over time.

In the beginning, those Node.JS codebases were clean and manageable. Then came bug fixes, changing requirements and refactors. 2 years worth of that led to something that was quickly becoming unmanageable.

But then came Go and, after a rewrite, everything was clean again! It doesn't matter than the code base is only 3 months old, I'm sure it's going to stay this clean forever!

But hey, should those Go codebases become messy a couple of years from now, I'm sure Rust will have matured into a worthy successor and, after a rewrite, we'll all have the cleanest codebases ever!


Similar path here, but we cleaned things up using TypeScript.

Its incredible how much easier things get when you need to refactor if you have types.


It's what devs are saying about any tech that's becoming popular.

It's much more useful to read a competent critique of Go (of which there are a couple) than post after post saying how everything is great. Everything can't be great, it's a basic fact of software engineering!


I can't remember anyone ever claiming javascript/node made their code cleaner. Speed and throughput were claims but not code quality.


I've been coding since forevs, and I really do feel like Go pushes you to keep clean code. Maybe the language, but a lot of it's just culture and leading by example.

Every time I peak into the source of a standard Go package, I'm blown away by how clean and simple the code is -- and it's a fantastic way to gain a deeper understanding of the language.

That has mostly not been my experience diving into std C library code, or quasi-standard stuff like boost...


I like the aesthetics of JavaScript. It makes the code cleaner because it doesn't require so much boiler plate. There - I said it :-)

Oh and compared to Go, I always point to sorting in Go. Just look up the library. I think it's awfully complicated, compared to JavaScript where you simply pass a comparator function. In Go you need a lot of lines to achieve the same thing.


Yes, every language/framework is good at something and bad at some other. They are just tools. What matters is what one builds. A lot of technical news these days are about tools, not products.


Sure, I can run with that analogy.

So a master woodcarver works with chisels, his "tools", for his entire life...30 years, and with them he turns bare wood into incredible works that the world recognizes as valuable art.

Someone hands him a chainsaw, which by all measurable metrics should allow him to do the work 10x faster because, of course, it is more powerful, modern, and designed by "superior minds" whom understand IC engines, gearing, etc etc.

Does it? And should he switch?


I think what I want for Christmas is a language with C syntax and keywords, no header files, no GC, ships with a library that has everything (threads, http, websockts, crypto). This new language takes all the bad parts of C and throws them away and does not care about backwards capability. Call this new language C++ or whatever.


Yes, of course. Chainsaws are an ideal tool for large scale wood carving. https://www.youtube.com/watch?v=tPJ9t3jIBjA


For what it's worth, I moved to node.js late and even then only reluctantly. I only used it for one project, and found it to be a somewhat difficult experience, like I was fighting the language all the time. (It was still a step up from PHP which I'd been clinging to.)

I didn't realize how much I disliked JS playing "loose and fast" until I used Go with its rigidity.


I didn't. I tried node.js for a couple of months and it was like a breath of fresh air. But later on drowned on constant promises and never called back ;)


I understand the basics of Go, but do you have any advice on where to start using it for web app development? Any framework that you're using (if one at all)?


I've found the standard library to be more than capable for most CRUD style apps. You can add in simple middleware chaining using a library such as Alice (https://github.com/justinas/alice) and for passing around request contexts between them, you can use something like xhandler (https://github.com/rs/xhandler). If you want more performant or flexible routing, httprouter (https://github.com/julienschmidt/httprouter) has a nice feature set.

Maybe it's personal preference, but there's something more satisfying about the modular approach of building up an app using only components I need and understand, rather than starting with a magical feature-laden framework but quickly realizing you don't need half of what it does. I think Go aligns particularly well with this philosophy given its emphasis on composition.


That's the libraries I use, too. I really wish contexts were built into Go's HTTP library. Without contexts, you have to use global variables to accomplish things like per-request logging and access to configuration data.

Not to mention that since goroutines cannot be forcibly terminated, it's the only way to control the lifetime of a handler (e.g. applying timeouts).


You may be looking for https://godoc.org/golang.org/x/net/context which is likely to make it into stdlib in the 1.7 timeframe from what I've seen in various channels. Doesn't quite solve the global logging problem though.


Yep, that's the context we (I and the grandparent comment) are using.


I've picked out the following that I like:

- Gorp[1] for SQL stuff (I like that it "encourages" your program data structure to reflect your DB structure) - amber[2] for templating - gorilla/mux[3] for routing - gorilla/securecookie[4] for login/auth management (they have a sessions and context library too if you want that)

Go also has libraries that handle basic versions of most of these tasks (and these third-party libraries extend them). If you're building something simple they might be sufficient.

[1] https://github.com/go-gorp/gorp [2] https://github.com/eknkc/amber/ [3] http://www.gorillatoolkit.org/pkg/mux [4] http://www.gorillatoolkit.org/pkg/securecookie


I've used go-martini on a number of projects; it strikes a nice balance between performance (it's by no means the fastest Go web framework) and usability.


I've used Golang extensively for a few years now anywhere from ARM/Linux to x64/cloud based containers (and I admit, occasionally on Windows!). It's really a great platform, very robust and has an excellent ecosystem. I can't recommend it more highly.


I find it curious that virtually any negative or critical comments about Go get downvoted.


Because you don't insult someone when it's his birthday!


On the other hand, honouring people by roasting [1] them is also tradition. Maybe if the criticisms were funnier.

[1] https://en.wikipedia.org/wiki/Roast_(comedy)


Have they been constructive, or just random negative noise?


I've been having this vision for a while of making a HN-style site where you have to explicitly tag your comment as 'in agreement' or 'in critique'. (And also maybe a slightly hidden away, 'off topic, but that reminds me...' section.)

Then you could, for example, browse the ed column of birthday wishes & happy usage stories of Go, say on the left hand side, and then also, scroll through the op-ed right column of dissenters and critiques.

There's just something very disheartening about having a bunch of "anti X" dominating what you were hoping would be a discussion of "X"; downvoting is certainly not the right solution -- it's fine to be anti-X, it just needs a little bit of its own space.


Slashdot had this concept of modifiers, so you could say "+1 Insightful" or "-1 Troll". "+1 Funny" didn't give you any karma.


Ahhh, slashdot, those were the days. :)

My idea is different, though -- the essence is

(1) you'd self-tag -- imagine clicking 'in support' or 'in opposition' to comment.

And then (2), those two different sets of comments would go into different parts of the page.

Maybe a two-column view? Maybe separate pages?

Basically, conversations in a single-section format like HN are constantly getting overrun by criticism. Criticism is interesting and has its place, but it tends to be noiser, and it's disheartening when it's getting in the way of something you want to be excited about.


I'm surprised to not see any mention in the comments about the biggest change coming in 1.6: the package vendoring mechanism. This has been a big missing piece for awhile and I'm glad they're addressing it in an official way.

I was super excited for the cross compilation abilities on Go 1.5 and now I have something else to be super excited for in Go 1.6, can't wait!


I was confused by that. Is this going to be any different than GO15VENDOREXPERIMENT which we have now?


I guess I was hoping for a composer-like versioning system, but I suppose that's not a given?


It would be a surprise to me, but we'll see. I haven't seen much discussion since the vendor experiment, weirdly. (But I haven't been looking, either.)


I've started working in Bioinformatics. The languages in use and libraries seem to by Perl/Python and some java. Except for the stuff that needs to be fast, then its C. Although I notice some movement to use Rust instead of C (having installed some C based tools having package management would be glorious).

It would seem the concurency model of go would be a great fit for a lot of those existing python/perl tools. My searchingg for projects show it hasn't really taken off in this domain. I might start rolling my own packages.

How is the package management in Go? Data structures and String manipulation? And is does that concurency scale across nodes (al la MPI)?


I'm a computational biologist that recently ported our webserver (genestation.org) from Tripal (PHP/Drupal) to Go. The performance gains were huge, but the simplicity of development and deployment was even better. I'd strongly recommend Go for a biology web server. However, Biogo is not remotely as far along as Biopython or Bioperl. Also, Perl beats Go for ease of string handling. Unfortunately, there is no equivalent to Numpy/Scipy in Go. Despite these areas of weakness in the ecosystem, I have switched to Go entirely except for one-liners and one-off parsing in Perl.


> Unfortunately, there is no equivalent to Numpy/Scipy in Go.

We're trying! https://groups.google.com/forum/#!forum/gonum-dev github.com/gonum . Bug reports and contributions encouraged.


Thanks. They new site is snappy.

Tripal I had never heard of. It uses "Chado" db schema which I have heard of (though flybase) which while flexible isn't always performant.

Performance gains and simplified development are so appealing (I have 12 tools to maintain in Java/perl/php)..

Biogo is what I was looking for. https://github.com/biogo/biogo


You said above you 'may start rolling your own packages'. If you're interested in helping develop the numeric ecosystem, please come join us at gonum https://groups.google.com/forum/#!forum/gonum-dev github.com/gonum.

Dan (the lead developer of biogo) is very competent and I'm sure would love bug reports and PRs in biogo as well.


Chado does have substantial performance problems for use as a webserver backend. We use elasticsearch for full-text search and as JSON document store, which improves performance substantially.


Golang and I have had a mainly wonderful relationship. I think that the performance and concurrency features that it brings to the table are unparalleled. No that Golang is just 6 years old and probably has a few more decades of relevance. Although they need to do something about the compilers as the compiled binaries get more bloated with each release.


I have written tons of services in Go. What I love about it is stability. Services written in Go are rock solid.


I've used Go for a couple years but am only just writing my first production system in Go. I think one of the major complaints is that it's use-cases are ambiguous to beginners. Go, IMO, is a systems language and should not be the first thing you pull out when someone says "write a web app".

I think Go has a very limited use case, but it is incredibly good for that use case. If I had to define it right now it would be along the lines of "Highly concurrent micro-services (re: small code bases) that requires decent performance (memory + speed) in a somewhat distributed fashion". Obviously it's not perfect but it's the feeling I've developed recently.


Go started as a niche language and worked well for that niche, but like all niche techs that become dependencies, they tend to get bigger overtime. Go success is undeniable and is reaching a critical mass where there will be no going back.

There are alternatives but most of them aren't backed by a big corp like Google, so they will have to succeed in their respective niche before getting widely adopted. I wish that wasn't the case cause languages like D,Nim or Crystal are really good and way more enjoyable to write in my opinion. Out of all of these(including Go) one will be the next big language, no question as people move from dynamic or VM backed languages (for good reasons).


Really agree with this. Its not my go-to language for many things that could be done with a simple script, but its good to have it in the toolbox when i do have those sort of problems. I think if i was writing a high-performance API i would use Go


I would have used Go for an API recently until I found out the AWS SDK for Go isn't production ready. Libraries still have some catching up to do but will only get better with more time and testing.


Go made me excited about programming again. Love it.


Anyone happen to have a link to a good guide/tutorial for building a mobile backend in Go with gin? Or know of a public github repository with a good sample project. I've never done any backend work, and I'd like to build a backend for a simple iOS app to start.


Happy anniversary.

I replaced python with go in my projects and i'm so happy!!!


Thank you! Go has made me enjoy programming once again.


All I can say in words is - thank you.


Despite the hype in the beginning, it never caught my attention.


呵呵


I'd say after 6 years adoption rate has been rather lackluster


That certainly doesn't feel the case where I am. I suppose it may depend on your work field and environment.


Compared to what other new language?


Java, JavaScript, PHP, C# and ActionScript each got pretty good traction within their first six years as new languages. So did Ruby amongst the language community (of Japanese speakers) it originated from. As others have mentioned, Swift has had a good adoption rate.


maybe not specific to language, but compared to projects like Angular, React etc... Go has much less traction. Swift is a new language and is already much more widely used.


Not going to debate your claim, but Swift is an unfair comparison, as it is practically forced upon you if you want develop for one of the most important platforms today (you can of course still write stuff in objC, but Apple has made it clear that you'd better learn Swift).


>[Swift] is practically forced upon you if you want develop for one of the most important platforms today

>Apple has made it clear that you'd better learn Swift

Can anyone point to any statments to this effect by a leader at Apple? I haven't found any with a web search.


what are the advantages of swift? Having programmed in neither, swift looks like a toy language to me


In a golang conference, the presenter talking about youtube's vitess said: "If vitess servers are down, then youtube is down. That's how golang is crucial for youtube"


Angular, React etc. are not languages. Comparing Apples to Oranges my friend.


Apple has a large impact. Like them or not, they tend to affect technology fast.


Aren't the design choices and intended use cases vastly different though? Could this explain some of the difference in traction you perceive?


https://twitter.com/jamwt/status/629727590782099456

What the heck are you talking about. Who uses Swift on this sort of scale? This is just one of the many MANY large companies using Go to power their core infrastructure.


Go brings some good things to the table, yes. I've seen it's popularity rise in recent years, but it seems to be rising slowly. There are a ton of companies that can be listed for almost every technology.

Node is another technology I would put ahead of Go as far as adoption. Maybe Go will get better, to me, it's too different than a lot of what I see day to day with Java, C#, Python, JavaScript and on and on. The part I love about Go is that it handles garbage collection, other than that, it's atrocious looking C like code.


Go syntax does indeed have a distinct lack of ribbons, bows, and lace doilies.


> Go brings some good things to the table, yes. I've seen it's popularity rise in recent years, but it seems to be rising slowly. There are a ton of companies that can be listed for almost every technology.

Then name any company using Swift to the level Dropbox uses Go, or retract your claim.

Go code looks nothing like C other than general brace styling. I can't decide if you're trolling or just genuinely this ignorant.


> What the heck are you talking about

> I can't decide if you're trolling or just genuinely this ignorant.

Stuff like this breaks the HN guidelines. Please edit it out of your comments when posting here.

https://news.ycombinator.com/newsguidelines.html

https://news.ycombinator.com/newswelcome.html


I've had this message several times, but "What the heck are you talking about" doesn't break any rule whatsoever that I can find. In fact I fail to see how it could be toned down anymore. Are we not permitted to express confusion? Is 'heck' not the lightened American friendly version of 'hell'?

How much more would you like me to blunt what I say in order that it doesn't violate unclear rules?


What you posted was uncivil. "What are you talking about" adds no information and is a variant of name-calling. Asking whether someone is "trolling or ignorant" is also name-calling, just with a branch in it. And "name X or retract your claim" is a form of intellectual bullying, so also uncivil.

Any substantive point you have will become sharper once you edit such rudeness out, so it isn't a question of "blunting", but of being respectful. Even if you don't respect the person you're talking to, you need to respect the community by holding yourself to a higher standard.


>Go code looks nothing like C other than general brace styling.

I disagree. The one thing that makes Go code look more like C than other C descendants like Java, C#, JavaScript, Swift and even to some degree C++ is its error handling style. Having a seperate error value is of course a big improvement over C but visually the error checking code following many statements appears a lot like C.

And the second reason is that Go has pointers with a syntax modelled after C.

So in the eyes of the 90% or so developers who have been using mostly Java, JavaScript and C# for 15 or 20 years, Go has to look a lot like C.


Just stating my opinion, not trying to troll. I said "C like" because it is very much different than any C like language I'm used to. Dropbox was using Python as a main technology stack not that long ago so I'm not all that surprised they are seeing huge gains using Go. If Go gains more traction I'll consider using it, until that time, 6 years have gone by and I personally haven't seen anybody asking for Go in the Washington DC metro area.


> Dropbox was using Python as a main technology stack not that long ago so I'm not all that surprised they are seeing huge gains using Go

They still use Python if you read down the Twitter thread, but I can name so many more. Cloudflare for example.

The likely reason you see such a difference is that the languages are suited to different things. Swift for example is all but mandatory for iOS apps, and so this is not adoption but migration. If you're just looking for small freelance projects then I expect Go will be a long time coming, but if you're looking for large infrastructure work you'll find an awful lot of people very interested in Go.


Angular...React, are you serious? Haven't even tried Go tbh but I wouldn't even dare to make such a comparison on HN or anywhere else for that matter. You just don't do it. It's like saying that Go sucks, google maps is better.

Who cares about adoption rate? Is PHP the best language to make websites because of it's popularity? Hell no!

I tell you what I care (and I know I will eventually pick Go for these reasons):

- concurrency - parallelism - stability - speed - community - libraries - proper use of hardware - small footprint


[flagged]


As for why you were downvoted: Accusing the majority of users on a forum of being trolls usually doesn't fly and it didn't fly this time either.


Go's syntax is pretty much C-like though. Try comparing Go to Lisp, Pascal, Python, Visual Basic, COBOL, FORTH, etc etc.

But at the end of the day, syntax is really just a superficial element of a language. Particularly when you're comparing Go with very syntactically similar languages such as Java, JS and C#.


Actually one of the guiding principles of Go's design is that syntax is anything but superficial. It affects nearly all aspects of your design. Everything from the parser to the compiler to the stdlib. Syntax is the UI/UX of your language. Dismissing syntax as superficial is a mistake.


Imperative languages really aren't massively different in the grand scheme of things. Sure, some are more OO than others, different type systems, and so forth. But you do more or less tackle the same problems with similar kinds of solutions. So a lot of the time, the syntax changes are relatively superficial compared to the complete mindset change you require if you were to tackle the same problem with a LISP, or Prolog, stack-based languages, or even a procedural SQL (albeit to a lesser extent).

I do welcome the breadth of choice we have in programming languages, but sometimes we get too caught up on the finites of one language of a particular sub-genre when compared to another language of the same sub-genre. Particularly when a good programmer should be more interested in coding good logic and thus understand the paradigms enough to swap between the different languages of the same ilk with relative ease.


[flagged]


It is fairly clear by now that omitting generics is not an oversight, but rather a design choice. If you disagree, it sounds like Go isn't for you. Maybe it's time to just move on and ignore it instead of beating a dead horse.

I am always confused by the push to make every language exactly the same by using the same paradigms and features. Some languages try to take a different approach. If you can't figure out how to work within that paradigm, don't use it. Your comment is akin to complaining that Haskell doesn't support an imperative style.


>I am always confused by the push to make every language exactly the same by using the same paradigms and features.

More like: some paradigms and features have been proved useful, and experienced programmers ask for them in a language that lacks them.

And not indiscriminately, but usually only ask for them if that language is of a certain paradigm / family of languages were those things fit well with (e.g. few ask for immutability in Go, or logical programming in Javascript).

>Some languages try to take a different approach.

Yes, the wrong one.

>If you can't figure out how to work within that paradigm, don't use it.

A lack of a feature is not always a "paradigm".

Besides, by the same logic, every language is perfect as is all the time, and users and potential adopters should not ask for anything new.

The lack of closures in Java for ages is a strong counter-argument to that. Or the rejoicing by which people adopted "auto" in C++. And tons of other examples, besides...

>Your comment is akin to complaining that Haskell doesn't support an imperative style.

More like his comment is akin to complaining that Java doesn't have Generics (pre 1.5).


Please just stop. This is not an objective issue. I for one have spent the last 2 years using Go to build a very performant system which is used by thousands of Bitcoin day traders every day. It's fast, stable, and easy to modify. I have never felt held back by a lack of generics.

And yes, I've spent plenty of time using languages that do support generics. It can save you time but I've found it also enables "looser" code, which can be more error-prone. In fact one of my favorite things about Go is how restrictive its type system is. I feel a lot more confident about my code doing only what I think it's doing when using Go.

If they find a way to introduce generics while upholding Go's other strong points (fast compilation being another), then great. But it looks like it's not trivial.

If the language is not for you, move on. There are plenty of us who are perfectly happy to write code without generics. Your condescending remarks are entirely unproductive.


The tired old argument gets trotted out again. If an important, beneficial addition to the language is missing then it's by design and if you don't like it go use something else.


>Please just stop. This is not an objective issue.

When it comes to computer science generics have been an accepted part of PL research for decades. The extra expression power they give and the paradigms they enable are neither controversial, not something that's up to individual tastes to judge.

Someone might not like them subjectively, but that's not different than someone not liking closures, or map or any other established thing. People will always have their preferences.

>I for one have spent the last 2 years using Go to build a very performant system which is used by thousands of Bitcoin day traders every day. It's fast, stable, and easy to modify. I have never felt held back by a lack of generics.

That doesn't prove it's not an objective issue, just that a specific use case, in a specific domain, didn't need it.

Or even more precisely, that a specific programmer didn't feel the need "held back" by their lack. Perhaps others would feel "pushed forward" by their presence.

For example, I mentioned Java above, who only got Generics after 10 years. Tons of far bigger Java programs than the one described have been created with Java-without-Generics (from financial services to automobile controllers).

All those projects weren't any "proof" that Java doesn't need Generics (and/or closures). Just that you can do without them too (which is true -- nobody argues that you can't).

Besides, isn't Paul Grahams whole "Blub" concept based on the idea that people using languages without X features have little means to understand their importance (and what they're missing)?

In any case, there are counter-examples to what you write too: several posts from teams that have used Go in production that say they like it but still lament the lack of generics.

>And yes, I've spent plenty of time using languages that do support generics. It can save you time but I've found it also enables "looser" code, which can be more error-prone. In fact one of my favorite things about Go is how restrictive its type system is. I feel a lot more confident about my code doing only what I think it's doing when using Go.

Generics are not "loose", if anything they're even tighter type-wise than what Go makes you do to overcome their absence. Either you create concrete types for everything, ad nauseum, or you go "loose" and use interface{} and the like, throwing a lot of assurances out of the window.

>If the language is not for you, move on. There are plenty of us who are perfectly happy to write code without generics.

Again, happiness doesn't say much -- that's personal preference and can't be debated.

Java programmers were perfectly happy to write code without Generics and Closures for like 15 years too. Most were even oblivious that those things existed in the PL world at large. Javascript programmers suffered without correct scoping or an import system for 20 years, etc.


It's funny that you mention Java because I have always avoided learning Java. Even from afar it grosses me out as a language. I actually think comparing Go to Java is silly because a lot of motivation behind Go's design came out of avoiding what was done to Java and C++.

The point is, plenty of companies manage to create very good production software with Go, without generics. I didn't mean to rest my argument on my personal anecdote. You can look to Google, CloudFlare, SoundCloud, Dropbox, etc. for reassurance.

If you have a suggestion on how generics would fit into Go, I think the Go team would be happy to read your thoughts: https://groups.google.com/forum/#!forum/golang-nuts.


>It's funny that you mention Java because I have always avoided learning Java. Even from afar it grosses me out as a language.

May I guess you're either some old Lisp/Smalltalk etc veteran, or, much more probably, someone who entered IT after, say 2005?

Because back in the day very few thought of Java as "gross" -- it was greeted as a welcome change from the existing landscape which at its best was something like C++.


I'm 23, I haven't been around that long :)


Yeah, so the second case, someone who entered IT after 2005!

I guessed so, because back in the day (1995-early 00's) most devs outside of seasoned functional etc veterans (who were extremely few) or hardcore systems guys, saw Java in mostly positive light, and never considered it "boring" back then.

The change (for new devs to consider Java "boring" and lacking in features) happened sometime after 2005, with Rails entering, Javascript catching up, C# getting more features with 2.0 and 3.0.

(Consider than back then Scala, Go, Clojure et al weren't even started, and AJAX had just been made mainstream).


> When it comes to computer science generics have been an accepted part of PL research for decades.

Programming language "research" and computer "science" research has been irrelevant in the sausage industry for about four decades.

It's just like complaining accounting refuses to use category theory.


To add to your list C++ guys are still waiting for modules.


The Go faq doesn't agree with you.


You're both right. I'm paraphrasing, but the FAQ says "We will add generics if somebody can demonstrate that the value of doing so would outweigh the complexity it would add". I'm assuming nobody has demonstrated that, so they haven't added them.


Should really read "We will add generics if somebody can perform the impossible and convince the very stubborn and opinionated Go leadership that the value of doing would outweigh the complexity it would add".


You are both correct.

It is by design that Go does not have generics as the Go team have not found a design they feel works and they are unwilling to compromise the current design.

They may never.


Nonsense. Reread the FAQ. They are choosing to not implement generics. If someone can find a way to implement them without violating Go's design principles, they will. In other words, it's a choice. It's not that they just haven't got around to it.


Haskell does support an imperative style, supports it quite well even :)


> not an oversight, but rather a design choice

Why not both?


You can choose an oversight? Once chosen, it ceases to be, no?


I suppose it depends on the precise definition of "oversight". My understanding of the term allows it to be used when someone deliberately chooses a course of action, but not having taken into account the full consequences.


> I suppose it depends on the precise definition of "oversight".

Good luck; it's an autoantonym. In my experience, your usage is as common as many others, though.


Actually, Ho has generics and has had them from the beginning. But they're only available for builtin types (slices, maps), not for user-defined types/functions.


And you can see already that starts them onto the slippery slope as they don't support variance rules. Which leads to lots of boilerplate/runtime-typed code.


Will this ever end


I suspect it will end once Go adds generics. (Whyever it would want them.)


There are tons of reasons Go would want generics.


This discussion again


Feel free to downvote me if you want, but I'm skeptical about Go and what caught my attention in this linked article is the picture. Pretty much what I feel about Go. Was it a (sub)conscious choice?




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: