Me personally: I appreciate the simplicity of it. It's a great language for working with in a team. I wish it was more functional, and had better ways to handle errors, but the simplicity of it all was a breath of fresh air using it in a working environment.
>> You can find a gun to shoot yourself in the foot in any language.
Sure, but finding that one isn't particularly hard, which is what GP was responding to
I think Googles stamp gives it some legitimacy, but I think the much likelier explanation is that the values in Go and its design speak to frustrations a lot of people actually have. This thread is full of people arguing in favor of gos error handling. You can dismiss them all as cranks or sheep if you want, but I think that would be misunderstanding something.
None of these things were technically bankrupt (including Go), but their adoption curve would not have been what they have been without Googles name on it.
There's likely other OSS that's technically better, but did not have the network effects google-backed software had from day 1.
Assuredly not C++, nor Rust... No javascript, swift has become more complex apparently, not haskell... Not C... OCaml? No it has a weird syntax, French people and wanting to be different... Etc...
So no, Go has genuinely appreciable qualities that are not found anywhere else :o)
To me, there were a lot of obvious reasons to choose Go in a corporate environment where my success is graded on my ability to deliver and the quality of what I deliver.
For every popular Google project you read about there are many flops, including ones they appear to develop in spite of.
I suspect it's a bit more than the Google stamp of approval - the innate simplicity of the language is attractive, it has almost Python-like simplicity without the performance concerns, and it has a "one true way" approach to formatting that settles any bikeshedding arguments in dev teams.
It's not my personal favourite language - the poor error handling discussed in this thread, the mess of the package management system (I mean, Python has a mess of a package management system, but that's more forgivable in a language from the 1990s, not the 2010s), the lack of decent standard library collections, etc. But I can see the appeal.
Most people are not going to care enough (or have the time) to enumerate every single difference between go and Java, and why they prefer the trade off go makes. I use Java professionally, and go where I can, and there is a lot I prefer about go (I won’t pretend it’s uniformly better, though.)
And fwiw, me and you have gone back and forth about this question in many threads previously. I think asking it from such a high level is not going to very effectively get into the details that actually matter to people.
Finally, I also think a lot of what makes go preferable is not in the realm of language design (at least not the algebraic type theory kind) or specific features. It’s much squishier than that, and involves feelings about how teams work and what developers do in practice (and why they fail).
This is not true of Go, and we could just as well see just as many D, Java, C#, Haskell, OCaml posts, yet they combined are not as frequent “visitors”.
Go is a language made by Googlers, so its design helps with Google problems. And many of Google's problems are ones of scale.
* Go is straightforward to read. Any reasonably-competent college graduate should have little trouble understanding it and be able to become productive quickly. * Go compiles into completely static binaries. You don't have issues like "oops, the build system runs CentOS 7 but we're deploying it to Ubuntu 18.04 and their libc's aren't compatible." With containers, you can copy many Go programs into `FROM scratch` images and they will work fine, greatly reducing the attack surface area.
I used to dislike for Go for similar reasons to you and others, but after using it for a few years at $employer, I've come to appreciate its merits. Sure, it can be a bit annoying to write
if err != nil {
return err
}
again and again at first, but I just type 3yy7jp to yank+paste it as needed. You could also configure some editors to detect when you type `if err` and generate it automatically. It's also not uncommon for editors to fold the lines down into a single line.Errors in golang do not have stack traces, and wrapping errors is just an error prone way of manually (and apparently nonperformant way of) generating stack traces.
I had to add `CGO_ENABLED=0`
* sometimes.
It can also dynamically link stuff on occasions, depending what options you use.
Sure.
Difference is go does not have the complexity you can find in Java and quite opinionated. So you don't have to spend as much time working with the language inself and can focus on getting the job done.
Go is not as expressive and some other languages and does not have the same abstractions that make other languages more suited to be used while developing comlex software.
Thing is - in many cases you simple do not need any of it, but need a fast verbose language with good tooling.
Call it Java Light or something.
By having an overly simplistic language, you end up pushing more complexity onto the programmer and into the code base. There is no free lunch.
I find it much more sane to solve and express code in Java. You get terser, more to the point code that reflects the underlying logic more clearly, compared to having to read many lines or pages to understand what's going on.
Sure, I just don't see this as a problem.
As a result you have
a) a number of third party packages to chose from depending on your needs\opinions
b) you have a more verbose codebase, some people find it harder to deal witih while I find it easier to deal with.
>compared to having to read many lines or pages to understand what's going on.
Different people different ways of thinking I guess.
In my eyes Java code looks to much like a specification in for of a code. Easier to do a code review but harder to actually understand how it works. And I personally need this dive into internals to actually feel confident about the code.
>Could you elaborate on exactly what complexity in Java you're referring to?
I don't have too much experience in Java, but from what I've seen - Java has too many abstractions and OOP for the sake of paradigm and nothing else.
I don't want to learn about Gradle or Maven to understand how a package is working, I'd rather do it in code.
Consider even the current "Hello, world" example in Java (Yes, I know about the proposal about simplifying it), it is tedious, why would I need to understand public/private and classes before launching a simple program?
I fully agree it is a terrific piece of software, especially for industry-grade applications, yet it just isn't attractive.
Main thing IMO, is that you can start out writing pretty good Go code after 24 hours and just improve on your skills as a general programmer. With Java, after a few months you would still need to know about some methods or OOP tips/tricks, design patterns etc. to become proficient.
Many of the design patterns are useless bullshit, that is long superseded by a language feature, so that point doesn’t stand imo.
Go also has public/protected, it is just case-specific. If anything, that makes it harder to understand, how should I knew that Asd is different from asd beforehand?
Go reserved keywords: break, default, func, interface, select, case, defer, go, map, struct, chan, else, goto, package, switch, const, fallthrough, if, range, type, continue, for, import, return, var
Java reserved keywords: abstract, continue, for, new, switch, assert, default, goto*, package, synchronized, boolean, do, if, private, this, break, double, implements, protected, throw, byte, else, import, public, throws, case, enum, instanceof, return, transient, catch, extends, int, short, try, char, final, interface, static, void, class, finally, long, strictfp, volatile, const, float, native, super, while.
types do not enter the discussion
like, it's not as if the go type `float64` is also a go keyword
but i guess the java type `byte` is a java keyword? according to https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_k...
const true = false
in golang
The number of reserved keywords is not a bad thing. For example, I constantly missed `final` when I worked in golang. Just because a keyword doesn't exist does not make its usecase disappear. Same with other features like `enum` (extremely useful) and visibility rules. golang only has package private and public, not nearly as granular as one needs in practice, not to mention generating large CL's when changing the visibility rules of a function, as opposed to simply having a 1 line change. Sure you can ignore those use cases, but it doesn't mean that their usefulness disappears.
I'm not saying reserved keywords are bad. I'm saying there's much more to learn about Java to learn programming, Go is limited with its' keywords and 'features', which often results in more LoC, but makes it super easy to get going, run into general programming problems like using a variable instead of a reference to it, etc.
In Java, you spend much more time learning the features of the language itself, even simple things like (s)Strings are not easy to understand, then add classes, inheritance, UTF-16, adding other libraries, build tools, JUnit and many, many other things that are given to you with Go.
I don't see why learning language features is an issue. The language offers features to provide more correct and more expressive code.
golang does not solve the variable vs reference issue at all by the way, and in fact, introduces weird edge cases, such as nil interface not being equal to nil.
Why do you say Strings not easy to understand?
I want to learn programming before becoming an expert in the language. I feel like it's easier to do using Go. In Java you have to become a bit of both to be efficient.
By reading docs or some kind of "Go by Example"? The same way you learned the difference between `private` and `protected`.
I fail to see why I would go with go over java, besides.. perhaps some CLI app? With Graal even that can be implemented in Java.
The thing is in real life you have to deal with this kind of code most of the time. Because most of the time you deal with the old code or people who are used to some patterns you have to use too because you are part of the team.
Go enforces (kind of) a more barebones approach by default.
PS: I think it's poinless to compare two languages. We should rather compare real practices and read examples.
* Relatively simple syntax.
* "Good enough" expressivity-- nothing that's considered "missing" has been a true blocker for most projects.
* An easily accessible concurrency primitive, with the bonus that the runtime can choose to execute goroutines in parallel (when able)-- this comes with no required function coloring or split in a code base.
* A well opinionated environment packaged with the compiler: default formatter, default method for fetching remote deps, default documentation generator, default race detector, default profiler, default testing system.
* Decent portability-- can cross compile relatively easily from one platform to another, doesn't require a larger runtime pre-installed on the foreign host.
* "Batteries included" standard library.
* Inertia-- enough of an active community to pull what you need from the Internet, whether it's guides or code.
* A "good enough" type system to catch some errors before they become runtime errors.
* A "good enough" abstraction for operating on data with: structs, interfaces, and methods. With composition being preferred over inheritance, and embedding bringing handy sugar.
No language is perfect, everyone has an opinion, but for many people this is "close enough" to what they prefer to work with.
Gophers may just be a bit more vocal about it.
Java learned the right lessons and I'm quite excited to see their structured concurrency approach. No need to pass channels and contexts everywhere to manually manage hierarchies from what I gather.
I believe that uncolored async (Erlang) precedes colored async (python)
Correction: c# was the first language with colored aaync, still way after Erlang
I've even got a library for using futures in Go. https://stephenn.com/2022/05/simplifying-go-concurrency-with...
Another point is that they do share similarities, which might we might now just describe as being 'modern': They're generally procedual -- you organize your code into modules (not classes) with structs and functions, they generally like static linking, type inference for greater ergonomics, the compiler includes the build system and a packager manager, there's a good formatter.
The above are points for both rust and go compared to C/C++, Python, Java, etc.
So why do I like go? I think mostly it's that it makes some strong engineering trade-offs, trying to get 80% for 20% of the price. That manifests itself in a number of ways.
It's not the fastest language, but neither is it slow.
I really dislike exceptions because there's no documentation for how a function can fail. For this reason I prefer go style errors, which are an improvement on the C error story. Yes it has warts, but it's 80% good enough.
It's a simple language with batteries included. You can generally follow the direction set and be happy. It leads itself to simple, getting-things-done kind of code, rather than being over-abstracted. Being simple also makes for great compile times.
That I agree with.
But Go is anything but modern on a language front. It shares almost nothing with Rust, which actually has a modern type system (from ML/Haskell).
Even if we disagree about exceptions (I do like them as they do the correct thing most of the time, while they don’t mask errors, but include a proper stacktrace), go’s error handling is just catastrophic, being an update from c which is even worse is not a positive.
This differentiates go, rust, zig, odin etc., from languages like C++, Java, C#, Python etc. I think it makes sense to describe that difference as one of modern sensibilities.
I’m not a go developer. How does go document how a function can fail?
A Java developer can use checked exceptions so that some information is in the signature. For unchecked exceptions the documentation must explain.
I guess in Go the type of the error return value provides some information but the rest needs to be filled in by the documentation, just like the Java checked exceptions case.
There's no magic to it. Errors are values, so it's a part of the function signature that there's an error code to check. In C++ any function can throw an exception and there's no way of knowing that it wont.
It's true that go doesn't document what _kinds_ of errors it can throw, but at least I know there's something to check.
You can write huge code bases with it, the tooling is good.
You can use a moderately skilled work force to achieve good results. When some team members leave, you are not left with some wizardry code base behind.
For me, it's:
1) channels (and goroutines, of course)
2) explicit error handling (panics are actually fatal, in contrast to exceptions which are often even used for flow control)
3) easy (cross-)compilation - just go build
And probably a few more reasons I can't remember at the moment. It's just fun to write Go!
If you view the language as a safer super shell script, it becomes more obvious.
Go was hyped in the beginning, but I get the impression that now it isn't. The most persistently hyped language here is Python. Fortunately, we see more Elixir, Ruby and Go posts lately.
In my personal opinion it is just not a good language, and I think many judge it based on some false basis that it is somehow “close to the hardware” because it produces a binary. Like, the amount of time it is put next to Rust when the two have almost nothing in common..
It is very verbose, yet Java is the one that is called that, often by Gophers, which is much more concise. It has terrible expressivity, a managed language which is a perfectly fine design choice, yet seemingly every other language with a GC is somehow living in sin.
And still, it doesn’t fail to show up each day on HN.