Yes. The sell point of Go was supposed to be the queue type concurrency model. But that turned out to be marginal. In practice, programs use shared data and locks.
The real advantages of Go seem to be that it's reasonably simple and comes with solidly reliable libraries for web server side applications. The libraries are used internally by Google, so you know they've been exercised thoroughly.
With Python and Rust, there seem to be multiple packages for everything, and you get told "Oh, you shouldn't be using X, you should be using Y".
(Back in 2012, I filed a Python bug report on parsing ISO 8601 date strings. I'd found four library functions for doing that, all with bugs. Fixed in 2018, after years of bikeshedding.)
I recently had to evaluate using Go vs Rust vs Java (current) and while Go did bring notable resource usage bonuses compared to JVM, Rust seemed to give significantly more if we did switch.
The drawback of both Go and Rust for our group was that Java developers were so much more abundant in our market(not major technology hub city in the South).
I think cities with smaller amounts of talent have the same problem when trying to find Go and Rust developers of all skill levels.
This is a reasonable question, so I’m unsure why it’s downvoted.
It usually makes sense to talk about the memory overhead of the JVM itself, rather than talking about one of the languages specifically, like Java or Kotlin (but maybe Scala and Clojure are a bit different).
The tradeoffs for GC systems are complicated and not easy to understand. Go supports only one GC system, as far as I know, which does not move memory and attempts to minimize GC pauses. It sacrifices throughput and CPU utilization to achieve this.
The JVM can be tuned in many ways and there are a number of different options, from choosing different GC algorithms to different memory models. Most JVM algorithms will compact memory. Some are optimized for throughput and others are optimized for shorter pauses.
In practice, my observation is that Go’s GC pauses are, out of the box, shorter than what most people will get by tuning the JVM. This is probably the most critical property for writing backend services with high fanout, which is very common at places like Google.
I don't have a dog in this be cause all I do is write embedded firmware and crummy tools that run under windows. But low latency is a better choice than throughput most of the time. My gut says when a system bogs down failures due to latency hits you first.
I’m gonna go ahead and say that this is one of the reasons why people like Go so much. Latency is a big problem and becoming bigger as fanout increases, so the old defaults for tuning GC turn out to suck horribly.
However, the throughput penalty is very real and e.g. compiling a large codebase I’d much rather have throughput tuning.
Not needing to install/update a runtime on the target machine is an enormous win for shipping client-side software. For server-side software, maybe it's a small win. (If all you need to worry about is your own proprietary server environment, that's not a big deal, but shipping open source software that depends on the JVM leads to a lot of extra installation instructions and bug reports.)
The latest versions of Kotlin support multiplatform programming (and hence native compilation) and this feature is actively under development. The JVM is not necessarily needed if you go that route.
Kotlin barely has a standard library outside of the JVM. They only recently introduced experimental io support and the concurrency model is just plaim weird.
Yes that is what I mean with semantic differences.
I watched a couple of KotlinConf talks, it appears that JetBrains wants to be the next Borland (Kotlin == Turbo Pascal), using the JVM and helped by Android to bootstrap their own eco-system.
So even with multiple platform Kotlin there is only so much that you can use from each platform when deciding to go big like that.
I don't see it working and think if they want to survive they should focus on the KVM (aka Android).
Goroutines are still pretty darn light-weight and relatively "easy" to use. Compared to processes and threads, you can spawn thousands+++ with sane defaults and minimal overhead on crappy hardware. Having decent stdlib-support for things like mutexes and sync.pool, means using what works. But yeah, channels and "synchronization by communicating" was heavily oversold, more as a cool idea than anything to cargo-cult. There are many other mechanisms offered in standard lib that may be used to improve scalability and performance. Overall, Golang is overall "good" in many areas, do have some snags (but like in C/C++ these provides you with some lower-level control), though will not approach C-performance. So it's a trade-off to be able to use those sane defaults until bigger foot-guns are really, really required (avoiding premature optimizations).
They're really "green threads" or "fibers". Remember those? With a good way to avoid blocking on system calls, which Go has, it's a much simpler way to do sequential operations. No need for state machines, "promises", "futures", "async", or all the other hacks used to hammer an event driven model into a sequential model.
Go the language is simple, but the infrastructure around Go is where it shines, especially around tooling and runtime (especially now that versioning has been finally figured out).
There are some great pieces of tech that really push the boundaries forward in areas of scheduling and garbage collection.
Go also forces you to think about your data (data oriented design) versus designing objects, hierarchies and relationships, which I have come to really enjoy these days having left behind my days of architecting for the "enterprise"
Zing by Azul is very cool from what I've heard engineers talk about as well as marketing, though it being a proprietary beast definitely affects people considering using Java over Go.
Being able to use methods as function values is a strange criterion to use. By that definition, Lua would be a "rigid and inflexible" language because you need to use a lambda to pass a method around:
In my opinion, the main selling point of Go is a good ratio of performance and language. It’s reasonable fast and mostly straight forward to program with. The standard API is just incredible great in terms of documentation and uniformity.
There are things where I personally think they could have done better; generally nil-able values (SQL/JSON integration is awful sometimes) primarily.
Go is the worst programming language out there, aside from any other language I've tried so far.
Seriously though, besides being just a good solid balance between speed, ease, safety, etc without anything really exciting - there are a few cool things about Go that make you write cleaner programs: The biggest one for me (well, maybe after the concurrency model) was the whole implicit interface thing, alongside interface composition and avoiding Java-style class hierarchy. It just forces you to think in interfaces and avoid complex hierarchies. This leads to much cleaner elegant code-bases.
Edit: @CharlesW made me realize that @dvirsky is not bashing on the language, the comment below is a reaction to their choice of words, specifically to the first sentence. That being said, I will keep my comment as is for context. I would have chosen the word “boring” rather than “worst” to describe Go, but I am not a native English speaker so maybe “worst” is okay.
---
> Go is the worst programming language out there, aside from any other language I've tried so far.
Ha! Opinions, it’s always interesting to hear what other people thing about stuff I use every day.
I, on the other hand, enjoy programming with Go. It has opened a lot of doors in my career and I can even attribute my success to its existence. Roughly five years ago I was struggling to justify a higher salary in my home country; soon after I started using Go and promoting my projects people started sending invitations to interview for jobs in different companies. I took a chance and quit my job, traveled to the US, a few European countries and Asia, looking for a good company to build my next ±5 years of experience, and finally settled in one of the majors cities in Canada with a company that pays me considerably well to write programs in a language that you consider the worst out there.
But you know what? I understand your feelings, because I also have a programming language in mind that I consider the worst out there, but you will never find me throwing dirt at it or its community because I know there are people out there who enjoy working with it the same way I enjoy working with Go.
BTW, the parent commenter is saying that Go is their favorite programming language. They're using a form similar to "democracy is the worst form of Government except for all those other forms that have been tried from time to time", which was quoted by Churchill.
that's what happens when almost trillion dollar company puts enough resources into marketing of it's language and projects
and yet this almost trillion dollar company in almost 2020 doesn't bother (or can't figure out how) to implement basic generics support so you can't even implement a fucking set.
fuck google and fuck golang. specifically because how ubiquitous it has become. this is all super depressing.
It's funny you mention that since, although go is getting respectable use, I haven't seen that many shops in go. But I'm a Java guy and every other company is a Java shop in the bay at least. That's what I called ubiquitous.
I’m doing mostly infra work and have been for some years, with advent of kubernetes it’s really hard to avoid golang.
My personal preference (which is clojure) doesn’t matter much, I’m just really angry and frustrated how industry has settled on something so broken. Pick any non-trivial golang file and it’s 50% boilerplate, 45% passing errors around and about 5% substance. How did we end up with that in 2020? Ten and something years from now lambda calculus will be hundred years old.
Why do you think it's found the audience it has? I can only speculate, coming from Java, that maybe there is some amount of comfort in boiler plate. Less defaults and less magic can be nice. I like being forced to hardcode the defaults into the program and the like.
not sure this counts as flamewar, so i'm risking some sanctions, but still..
languages can be concise and code can be about the problem without any magic. looking at code for the sake of satisfying language limitations means not looking at the code for solving your problem. it may be comforting to look at boilerplate because you're familiar with it, but it's taxing away your ability to grasp the substance. visual locality matters because that's how our brain works and there can't be visual locality with boilerplate. furthermore everything that's visually remote has to fit in our very limited capacity to mentally juggle concepts, that's why locality and generality (fewer concepts to juggle) is important. golang lacks both generality and conciseness. i have no idea why it's found the audience it has beyond my initial angry comment and maybe also because it's "new".
Of course opinions about programming languages are allowed. You just have to do a lot better than "fuck google and fuck golang" and the rest of your comment above.
If you read the site guidelines, you'll see that we're looking for curious conversation here. Also this: "Comments should get more thoughtful and substantive, not less, as a topic gets more divisive." Since programming language opinions are pretty divisive, comments about them should be thoughtful and substantive.
Perhaps the first half of my first sentence made you so furious you didn't notice the second half :) Anyway, I really love Go, but I haven't written any in a long long time, which is a bit ironic since the cutoff point was when I joined Google.
I thought it would be another Turbo Pascal/Delphi with automatic memory management, instead it turned out to be just a little better than Oberon 2 + Limbo, brought back from ca 1992.
Still, better than increasing the LOC of C code available out there
After using Go and being forced to "think in composition," I loathe having to use inheritance when working in other languages. There's something about writing Go that feels crisp. When I'm having trouble making it do what I want, I almost almost realize that it was because I was doing something stupid and there was a simpler way.
Yes, exactly. But the cool thing is that it's improved me when I'm writing in other languages. The first big project I did after writing tons of Go was in C, and man was it a delight to write Go-style C. True, it wasn't nearly as elegant in syntax, and memory management was X1000 more difficult, but thinking in interfaces made everything much nicer.
Go is a great language with a great standard library. The big downside is, that you have to play compiler and write all the time boring algorithms yourself (because go has no generics).
Want to filter a slice -> do it yourself
Want to map a function over a slice -> do it yourself
Want to pop out a value of a slice -> a[len(a)-1], a[:len(a)-1]
...
There are worse things in the world, still it's the reason why I don't use go any more.
This is great, good choice! If you do need overly complex and convoluted ways, there's always java and Python. No need to pollute the simple and direct space.
My personal headache usually go along these lines: Why did I continue pile complexity onto the same codebase for too long, and could I've made simpler architectual and design choices earlier? (Ideas starts popping in for next project => filed)
Not sure I can really agree with this. I will preface the rest of this with saying I did have a good 4 years professional experience with Golang, more if you count my current gig with does involve working with it occasionally unfortunately.
It's main selling point is ubiquitous support for concurrency via a green-threaded runtime and standard library.
You could additionally argue compilation speed is very good.
Also it has a quite low latency GC, I think that is also an important feature of Go.
However that is pretty much where its pros stop and its cons begin.
Arguing for "simplicity" sort of falls apart given its rather expansive runtime. It's not really "simple" in the way C is and it's not "easy" in the same way Python/Ruby are.
I would instead say it's "easy to learn" but I would also go on to say that it's very hard to master because of the complex interactions between channels, strange behaviours that can be encountered with cgo. Sharp edges in the standard library is also another big one that places mastery out of the reach of most. I think this ends up being a net con as the investment required to reach mastery in Go is much higher than what is required to each competency in a language with a better force multiplier.
Lack of a reasonable type system given it's vintage, primarily no provisions for generics despite in-built generic data structures being the very foundation of the language - just not implementable in usercode.
Really poor quality packaging and distribution for the majority of its lifespan, even now Go modules have more sharp edges than is reasonable.
Go is plain awful from an expressivity perspective which results in verbose code and by extension impacts readability of business logic in particular.
I could go on but the reality is that it's not a pleasant language to use beyond it's core domain of shuffling bytes from one socket to another.
If you need low memory footprint + concurrency + performance then you probably want Rust. Higher upfront learning cost but much more pleasant thereafter.
If instead you want a workhorse language for less constrained environments I recommend Kotlin. It's a JVM language so there is some investment required to get your head around that ecosystem but in turn - huge return with access to full JVM platform.
Kotlin has all the features Go should have been built with, gets away with minimal faults despite great Java compat. Is fast enough for almost anything you might want to do. Great type system including awesome generics, including reified generics, data classes etc.
The only thing I wish Kotlin had that Go does is a fully async/coroutine aware standard library.
Rust is getting this with asyncstd but it could be a while before Kotlin gets the same.
In summary despite spending quite some years learning Go, writing some big and high performance programs in it I didn't learn to love it, I grew to find it tiresome and despite all my investment don't pick it up to solve problems except in very specific scenarios.
I’m really glad that I’m at the stage where my decision to use a language is not influenced by HN articles or especially comments.
Understanding the design decisions for languages, especially languages like C++, JavaScript, and (less so) Java, is a problem for historians and not really suited for a technical explanation. For Go this is less true, but for the sole reason that Go is less than half as old as any of the other languages I listed!
For this reason, I find the comparisons between languages of different “generations” to be pretty uninteresting. C++ is a mess, but the reasons why it is a mess are interwoven with the historical context of C++’s creation. JavaScript likewise.
The main reason why we talk about Go’s selling points relative to e.g. JavaScript or C++ is because Go is popular enough and supported well enough that you can defend writing your corporate project in Go, and has enough libraries that you’re not going to be in trouble the moment you need to something simple like call into cloud services or open an image file. But at the same point, a comparison to JavaScript is really boring because JavaScript is so heavily constrained by 25 years of historical baggage, and Go is not.
So I see there being two bases for comparing languages that make sense.
1. You are solving an engineering problem, and need to pick a language to solve it in. You need to evaluate the language itself, available expertise, community, tooling support, interop, libraries, etc. Your choice needs to be defensible in some way so that you don’t get fired for picking that language. For most environments, Go passes the bar and is defensible as a choice, but the elegance is not really that salient.
2. You are solving a programming problem, and want to pick a different language to solve it in to stretch your experience or see what other languages are like. For this, you might look at detailed comparisons between languages like Pony, Nim, and Zig. Elegance or other personal criteria are of prime importance here.
I don’t see a use case for comparing the elegance of Go, C++, and JavaScript.
> Go filled the blank of lacking of a static language which is still much flexible in the world.
What makes Go more 'flexible' than C++ or Java? The point about built-in concurrency does not speak to the flexibility of the language imo.
> For example, C++ doesn't support using methods (member functions) as function values.
I would argue this is a very minor 'feature', and not very useful in C++ - you can have member function pointers in C++. Many other statically typed programming languages have supported first class functions since long before Go was around.
> Java even doesn't support function values. A single-method interface is needed to simulate function callbacks.
It pretty much does support first class functions, with slightly different syntax in some cases. Java supports lambdas, method references, functional interfaces.
> Many languages introduce lambda expressions to add some flexibility. But this doesn't solve the rigid problem, member functions still can't be used as function values.
What is the benefit of having non-static member functions as function values in object oriented languages? Also, you seem to be only comparing Go with C++ and Java, Haskell has more powerful first-class function support than Go, as do a dozen other languages.
54 comments
[ 3.3 ms ] story [ 121 ms ] threadThe real advantages of Go seem to be that it's reasonably simple and comes with solidly reliable libraries for web server side applications. The libraries are used internally by Google, so you know they've been exercised thoroughly.
With Python and Rust, there seem to be multiple packages for everything, and you get told "Oh, you shouldn't be using X, you should be using Y".
(Back in 2012, I filed a Python bug report on parsing ISO 8601 date strings. I'd found four library functions for doing that, all with bugs. Fixed in 2018, after years of bikeshedding.)
https://blog.twitch.tv/en/2019/04/10/go-memory-ballast-how-i...
The drawback of both Go and Rust for our group was that Java developers were so much more abundant in our market(not major technology hub city in the South).
I think cities with smaller amounts of talent have the same problem when trying to find Go and Rust developers of all skill levels.
It usually makes sense to talk about the memory overhead of the JVM itself, rather than talking about one of the languages specifically, like Java or Kotlin (but maybe Scala and Clojure are a bit different).
The tradeoffs for GC systems are complicated and not easy to understand. Go supports only one GC system, as far as I know, which does not move memory and attempts to minimize GC pauses. It sacrifices throughput and CPU utilization to achieve this.
The JVM can be tuned in many ways and there are a number of different options, from choosing different GC algorithms to different memory models. Most JVM algorithms will compact memory. Some are optimized for throughput and others are optimized for shorter pauses.
In practice, my observation is that Go’s GC pauses are, out of the box, shorter than what most people will get by tuning the JVM. This is probably the most critical property for writing backend services with high fanout, which is very common at places like Google.
However, the throughput penalty is very real and e.g. compiling a large codebase I’d much rather have throughput tuning.
https://kotlinlang.org/docs/reference/multiplatform.html
I watched a couple of KotlinConf talks, it appears that JetBrains wants to be the next Borland (Kotlin == Turbo Pascal), using the JVM and helped by Android to bootstrap their own eco-system.
So even with multiple platform Kotlin there is only so much that you can use from each platform when deciding to go big like that.
I don't see it working and think if they want to survive they should focus on the KVM (aka Android).
So yes, there is a point, of networking.
There are some great pieces of tech that really push the boundaries forward in areas of scheduling and garbage collection.
Go also forces you to think about your data (data oriented design) versus designing objects, hierarchies and relationships, which I have come to really enjoy these days having left behind my days of architecting for the "enterprise"
There have been very low latency garbage collectors way before golang, see offerings by Azul for instance.
In fact, Go is really more flexible than many dynamic languages in several aspects.
There are things where I personally think they could have done better; generally nil-able values (SQL/JSON integration is awful sometimes) primarily.
Seriously though, besides being just a good solid balance between speed, ease, safety, etc without anything really exciting - there are a few cool things about Go that make you write cleaner programs: The biggest one for me (well, maybe after the concurrency model) was the whole implicit interface thing, alongside interface composition and avoiding Java-style class hierarchy. It just forces you to think in interfaces and avoid complex hierarchies. This leads to much cleaner elegant code-bases.
---
> Go is the worst programming language out there, aside from any other language I've tried so far.
Ha! Opinions, it’s always interesting to hear what other people thing about stuff I use every day.
I, on the other hand, enjoy programming with Go. It has opened a lot of doors in my career and I can even attribute my success to its existence. Roughly five years ago I was struggling to justify a higher salary in my home country; soon after I started using Go and promoting my projects people started sending invitations to interview for jobs in different companies. I took a chance and quit my job, traveled to the US, a few European countries and Asia, looking for a good company to build my next ±5 years of experience, and finally settled in one of the majors cities in Canada with a company that pays me considerably well to write programs in a language that you consider the worst out there.
But you know what? I understand your feelings, because I also have a programming language in mind that I consider the worst out there, but you will never find me throwing dirt at it or its community because I know there are people out there who enjoy working with it the same way I enjoy working with Go.
that's what happens when almost trillion dollar company puts enough resources into marketing of it's language and projects
and yet this almost trillion dollar company in almost 2020 doesn't bother (or can't figure out how) to implement basic generics support so you can't even implement a fucking set.
fuck google and fuck golang. specifically because how ubiquitous it has become. this is all super depressing.
What language would you want to work in?
My personal preference (which is clojure) doesn’t matter much, I’m just really angry and frustrated how industry has settled on something so broken. Pick any non-trivial golang file and it’s 50% boilerplate, 45% passing errors around and about 5% substance. How did we end up with that in 2020? Ten and something years from now lambda calculus will be hundred years old.
languages can be concise and code can be about the problem without any magic. looking at code for the sake of satisfying language limitations means not looking at the code for solving your problem. it may be comforting to look at boilerplate because you're familiar with it, but it's taxing away your ability to grasp the substance. visual locality matters because that's how our brain works and there can't be visual locality with boilerplate. furthermore everything that's visually remote has to fit in our very limited capacity to mentally juggle concepts, that's why locality and generality (fewer concepts to juggle) is important. golang lacks both generality and conciseness. i have no idea why it's found the audience it has beyond my initial angry comment and maybe also because it's "new".
https://news.ycombinator.com/newsguidelines.html
We've already to ask you this: https://news.ycombinator.com/item?id=20330069
If you read the site guidelines, you'll see that we're looking for curious conversation here. Also this: "Comments should get more thoughtful and substantive, not less, as a topic gets more divisive." Since programming language opinions are pretty divisive, comments about them should be thoughtful and substantive.
https://news.ycombinator.com/newsguidelines.html
Still, better than increasing the LOC of C code available out there
More examples: https://github.com/golang/go/wiki/SliceTricks
My personal headache usually go along these lines: Why did I continue pile complexity onto the same codebase for too long, and could I've made simpler architectual and design choices earlier? (Ideas starts popping in for next project => filed)
It's main selling point is ubiquitous support for concurrency via a green-threaded runtime and standard library.
You could additionally argue compilation speed is very good.
Also it has a quite low latency GC, I think that is also an important feature of Go.
However that is pretty much where its pros stop and its cons begin.
Arguing for "simplicity" sort of falls apart given its rather expansive runtime. It's not really "simple" in the way C is and it's not "easy" in the same way Python/Ruby are.
I would instead say it's "easy to learn" but I would also go on to say that it's very hard to master because of the complex interactions between channels, strange behaviours that can be encountered with cgo. Sharp edges in the standard library is also another big one that places mastery out of the reach of most. I think this ends up being a net con as the investment required to reach mastery in Go is much higher than what is required to each competency in a language with a better force multiplier.
Lack of a reasonable type system given it's vintage, primarily no provisions for generics despite in-built generic data structures being the very foundation of the language - just not implementable in usercode.
Really poor quality packaging and distribution for the majority of its lifespan, even now Go modules have more sharp edges than is reasonable.
Go is plain awful from an expressivity perspective which results in verbose code and by extension impacts readability of business logic in particular.
I could go on but the reality is that it's not a pleasant language to use beyond it's core domain of shuffling bytes from one socket to another.
If you need low memory footprint + concurrency + performance then you probably want Rust. Higher upfront learning cost but much more pleasant thereafter.
If instead you want a workhorse language for less constrained environments I recommend Kotlin. It's a JVM language so there is some investment required to get your head around that ecosystem but in turn - huge return with access to full JVM platform.
Kotlin has all the features Go should have been built with, gets away with minimal faults despite great Java compat. Is fast enough for almost anything you might want to do. Great type system including awesome generics, including reified generics, data classes etc.
The only thing I wish Kotlin had that Go does is a fully async/coroutine aware standard library. Rust is getting this with asyncstd but it could be a while before Kotlin gets the same.
In summary despite spending quite some years learning Go, writing some big and high performance programs in it I didn't learn to love it, I grew to find it tiresome and despite all my investment don't pick it up to solve problems except in very specific scenarios.
Understanding the design decisions for languages, especially languages like C++, JavaScript, and (less so) Java, is a problem for historians and not really suited for a technical explanation. For Go this is less true, but for the sole reason that Go is less than half as old as any of the other languages I listed!
For this reason, I find the comparisons between languages of different “generations” to be pretty uninteresting. C++ is a mess, but the reasons why it is a mess are interwoven with the historical context of C++’s creation. JavaScript likewise.
The main reason why we talk about Go’s selling points relative to e.g. JavaScript or C++ is because Go is popular enough and supported well enough that you can defend writing your corporate project in Go, and has enough libraries that you’re not going to be in trouble the moment you need to something simple like call into cloud services or open an image file. But at the same point, a comparison to JavaScript is really boring because JavaScript is so heavily constrained by 25 years of historical baggage, and Go is not.
So I see there being two bases for comparing languages that make sense.
1. You are solving an engineering problem, and need to pick a language to solve it in. You need to evaluate the language itself, available expertise, community, tooling support, interop, libraries, etc. Your choice needs to be defensible in some way so that you don’t get fired for picking that language. For most environments, Go passes the bar and is defensible as a choice, but the elegance is not really that salient.
2. You are solving a programming problem, and want to pick a different language to solve it in to stretch your experience or see what other languages are like. For this, you might look at detailed comparisons between languages like Pony, Nim, and Zig. Elegance or other personal criteria are of prime importance here.
I don’t see a use case for comparing the elegance of Go, C++, and JavaScript.
Lack of generics is an obvious weak point in Go.
> Go filled the blank of lacking of a static language which is still much flexible in the world.
What makes Go more 'flexible' than C++ or Java? The point about built-in concurrency does not speak to the flexibility of the language imo.
> For example, C++ doesn't support using methods (member functions) as function values.
I would argue this is a very minor 'feature', and not very useful in C++ - you can have member function pointers in C++. Many other statically typed programming languages have supported first class functions since long before Go was around.
> Java even doesn't support function values. A single-method interface is needed to simulate function callbacks.
It pretty much does support first class functions, with slightly different syntax in some cases. Java supports lambdas, method references, functional interfaces.
> Many languages introduce lambda expressions to add some flexibility. But this doesn't solve the rigid problem, member functions still can't be used as function values.
What is the benefit of having non-static member functions as function values in object oriented languages? Also, you seem to be only comparing Go with C++ and Java, Haskell has more powerful first-class function support than Go, as do a dozen other languages.