News for hackers. Stuff that matters.
Re:Thirteen Years of Go by Xeoncross on Friday November 11, 2022 @10:12AM (#33561775)
I've enjoyed writing Go for years. However, it's not been the language that does it for me. It's been the combination of features and ecosystem that makes it a default.

It's hard to explain, but the language is one you can throw into a team of random developers and come out with benchmarks, tests, CI/CD pipelines, unified code formatting, and good parallel work models (via goroutines) almost every time. Builds are instant. Built artifacts are a single binary - not 1,200 files that must be moved. Every single package that has any traction is both easy to read and has documentation inline or via published go.dev docs.

It's easy enough the frontend JS guy can write it. It's complex enough you can use goa.design or go-kit to auto generate openapi specs and complex microservice designs that support multiple transports (like gRPC). Errors always get handled because the linter points them out and the devs don't cheat by setting up multi-function try/catch blocks.

I've had less issues with production Go applications than any other language. I don't want it to win over Rust though, Rust is awesome. I want Go to replace Java.

Re:Thirteen Years of Go by jjice on Friday November 11, 2022 @10:27AM (#33561973)
Wholely agree that Go tooling is fantastic, especially since most of it is bundled and directly supported by the language. Honestly my biggest gripe is nillability, but it really doesn't bite me nearly as much as it did in Java or C#.

There's a reason it's sliding into the "boring and effective" (that's a good thing) camp of languages, but it's still got some cool factor.

Re:Thirteen Years of Go by tptacek on Friday November 11, 2022 @10:29AM (#33562000)
Strong agree. Go isn't my favorite language, but it is my favorite programming tool.
Re:Thirteen Years of Go by makestuff on Friday November 11, 2022 @10:46AM (#33562235)
Yeah I was at a startup where maybe 10% of engineering had used go before and 20% had used Java before (it was a PHP monolith so most people were PHP developers). The Java code that was written was pretty awful (I was hired probably due to my java experience, so I had a decent idea of good java). However, the Go services were actually really good. There is something about having a simple language that works really well for backend CRUD services.
Re:Thirteen Years of Go by nogridbag on Friday November 11, 2022 @12:21PM (#33563641)
I think the main difference is there's just an order of magnitude more awful Java devs than Go developers due to Java being the most popular backend language for N years.

If the timeline was flipped and Java was the new language on the block while Go had been around for 25 years, I bet you'd see the quality of Java code was vastly superior simply due to Java attracting passionate developers interested in learning new technology.

I still see Java devs with 15-20 years "experience" coding like 1st year CS students. It really wouldn't matter what language they were coding in.

Re:Thirteen Years of Go by rob-olmos on Friday November 11, 2022 @02:25PM (#33565491)
What sticks out most for the Java code being pretty awful? Was the PHP code just as awful too in similar aspects?
Re:Thirteen Years of Go by kaba0 on Friday November 11, 2022 @02:27PM (#33565532)
Go is not really an easier language than Java, though.
Re:Thirteen Years of Go by throwaway894345 on Friday November 11, 2022 @02:56PM (#33565958)
Back in 2012 I was considerably better-versed in Java (it was the main language for my CS education and a bunch of my hobby stuff). Still, I ended up picking Go because it was so much easier--no need to deal with Maven or Gradle or the alternatives, no need to pick a testing framework or a test runner, no need to configure CI jobs to publish documentation or source code packages, no need to run some external web server process, no need to worry about runtime dependencies (including the JVM itself), etc. No need to navigate an ecosystem (including stdlib) riddled with inheritance and other antipatterns, etc. No need to get a master's degree in tuning the JVM. Text editor plugins just worked. `gofmt` existed and was ubiquitous. The language itself was far smaller and it had native, idiomatic value types from inception!. Everything about Go was just so much easier than Java.
Re:Thirteen Years of Go by gw98 on Friday November 11, 2022 @11:04AM (#33562495)
Agree on all points.

I'd like to add that it just tends to not punch you in the balls. I originally picked it up trying to solve a simple web hook integration problem. I had a Python Flask app running which received a webhook, did some data transformation and did a POST to an API. After spending a whole morning pissing around trying to get uWSGI, systemd via ansible etc working I went for lunch. Came back, learned enough Go and had it working in a single binary with systemd unit before the end of the day without any 3rd party packages, server mechanisms, dependency management, futzing. It just worked. The same code has been moved into docker, then into kubernetes over the last few years with no change, no bugs and no headaches.

Re:Thirteen Years of Go by alyandon on Friday November 11, 2022 @02:16PM (#33565351)
Similar experiences with Go vs Java and Python. One thing that has stuck with me to this day was how quickly I was able to write a proxy to distribute keys consistently across a set of Redis servers to break out of a bottleneck in an internal processing pipeline.
Re:Thirteen Years of Go by traceroute66 on Friday November 11, 2022 @02:41PM (#33565721)
> I had a Python ....

IMHO, the biggest win of Go over anything Python is the single distributable.

You write once. Compile (or cross-compile) once. Distribute the binary. Job done.

Python you've got the hell of dependencies. Write your script once, but then users have to endure pip hell for the hundreds of libraries you've depended on. And then the potential different dependencies between different Python stuff.

Go is awesome for that and the Go stdlib has 80+% of what most people need.

Re:Thirteen Years of Go by greymalik on Friday November 11, 2022 @03:10PM (#33566140)
Are there reasonable Go alternatives to pandas, numpy, and sklearn?
Re:Thirteen Years of Go by traceroute66 on Friday November 11, 2022 @05:09PM (#33567548)
> Are there reasonable Go alternatives to pandas, numpy, and sklearn?

You got me there. That is one of the things I keep asking Santa to bring me for Christmas. ;-)

I wish someone would come along with a competitive Go ML lib. That would be awesome with a capital A !

There are one or two niche libraries around for specific tasks (e.g. anomaly detection) but there's no broad-scope general ML library.

Re:Thirteen Years of Go by Xeoncross on Friday November 11, 2022 @06:05PM (#33568021)
Yes, I would also like better C interop speed and better GUI toolkits for desktop apps/games. But hey, that is why we have Rust.
Re:Thirteen Years of Go by throwaway894345 on Friday November 11, 2022 @02:50PM (#33565855)
Also, you can run that Go binary on any Linux system whereas with Python you'll be lucky if you can run on any non-Ubuntu/RHEL Linux system. Moreover, that Go binary will be like 10% of the size of a Python artifact (which amounts to significantly faster deployments and cold start times for things like Lambdas) and it will perform about 2-3 orders of magnitude faster than Python and there will be headroom to optimize (whereas with Python you're usually not going to eek much performance out beyond the naive implementation without substantially overhauling the architecture).
Re:Thirteen Years of Go by ColonelPhantom on Friday November 11, 2022 @11:38PM (#33569997)
I work on a Python/Django project, and frankly, that hasn't been my experience at all. Poetry makes per-project dependency management using venvs a breeze. There are a few deps on native libraries, such as libjpeg, so you do need to make sure those are installed, but the needed libraries are quite easy to find on most systems, and our Dockerfile only lists a dozen or so apt packages. There are also a lot of Mac users on our team, and they don't have any issues either.

Sure, it's not as nice or compact as a single binary, but "you'll be lucky if you can run on any non-Ubuntu/RHEL system" is massively overblown.

Re:Thirteen Years of Go by tech_tuna on Friday November 11, 2022 @11:12AM (#33562611)
Go has been an acquired taste for me. I still don't love its syntax but the tooling and interesting combination of properties (GC, compiles to a binary, strongly typed) are what ultimately won me over.

It's perfect for middleware, APIs and CLI tools.

Re:Thirteen Years of Go by KingOfCoders on Friday November 11, 2022 @12:19PM (#33563619)
I currently write a SaaS website in Go after doing quite some Rust. I do prefer Rust as a language - it's more expresive and I greatly prefer Result<> over error, but it has two major downsides for me compared to Go. First compilation is much slower and Go feels like a non-compiled language because of the compilation speed (my last startup I've used Scala with horrendous compilation speeds, the main reason not to use it) The second is the borrow checker. It's excellent mostly (love explicit mut) but fails for me for structs with sub-structs coming from different owners. Very fast you have Arc<> noise everywhere. A simple GC as a -gc=on with auto-arc for variables without lifetime annotations for people that don't need Rust for embedded applications would be a dream come true.

I also love 'import "embed"' in Go to embed web files (templates) inside a binary and then deploy/manage that one binary with systemd with zero downtime updates with systemd port activation. Slick.

Re:Thirteen Years of Go by TrustPatches on Friday November 11, 2022 @01:50PM (#33564995)
Not sure if it’s an exact parallel, but you can also embed files into rust binaries with “include_bytes!” and “include_str!”.
Re:Thirteen Years of Go by 5e92cb50239222b on Friday November 11, 2022 @02:24PM (#33565485)
It's a bit more advanced than what Rust macros provided last time I checked. You can shove whole directories in there and then traverse them or serve as static resources with pretty much one line of code.

Random blog post with a few examples:

https://blog.carlmjohnson.net/post/2021/how-to-use-go-embed/

Re:Thirteen Years of Go by TrustPatches on Friday November 11, 2022 @03:44PM (#33566547)
Very cool, I guess one the the advantages of rust macros is that you could write your own to do something more advanced in theory
Re:Thirteen Years of Go by super_flanker on Friday November 11, 2022 @03:53PM (#33566666)
You can do the same in Rust with include_dir[1]

1: https://docs.rs/include_dir/latest/include_dir/

Re:Thirteen Years of Go by scruple on Friday November 11, 2022 @04:45PM (#33567286)
I've gone as far as embedding a ReactJS app inside of Go's embedFS. It's pretty damn powerful.
Re:Thirteen Years of Go by surajrmal on Saturday November 12, 2022 @11:22AM (#33574479)
You can avoid Arc in rust the same way you avoid mutexes in go - use channels instead. I find programming rust with channels between tasks feels quite ergonomic. Also, at least to me, it seems like it's a no brainier to pick a language with a GC if your target runtime environment allows for it.
Re:Thirteen Years of Go by Casperin on Saturday November 12, 2022 @12:14PM (#33574980)
Mine does. Still picked Rust, and so happy I did. The type system alone does it for me.
Re:Thirteen Years of Go by nicolashahn on Friday November 11, 2022 @12:39PM (#33563930)
Slight counterpoint - I have written Go in the past and now am working with Kotlin and to be honest, I prefer it. I wouldn't mind Kotlin being the new Java rather than Go.
Re:Thirteen Years of Go by za3faran on Friday November 11, 2022 @01:36PM (#33564801)
Java is the new Java :) With features like records, virtual threads, pattern matching, sealed types, string templates, and more to come, it's shaping up very nicely.
Re:Thirteen Years of Go by Xeoncross on Friday November 11, 2022 @01:50PM (#33564976)
The compile times and the fact it takes 10x the memory for a lot of services is certainly something I would like to see addressed. Not to mention that Java for things like serverless has painfully slow startup times.

Java runs nice and quick when it's ready, but it's slow to get there and quite a memory hog.

Re:Thirteen Years of Go by kaba0 on Friday November 11, 2022 @02:32PM (#33565600)
Compile times? Besides gradle’s startup time, java compiles just as fast as go imo. Go barely does any optimization, but javac does even less - so I don’t really see it a problem on actually similarly sized projects.

Memory usage is a tradeoff — a good GC works best with a bit more overhead.

Re:Thirteen Years of Go by erik_seaberg on Friday November 11, 2022 @03:14PM (#33566188)
I want the compiler doing as much work as it possibly can. If they can somehow make the compiler faster, I guess that’s nice, but I don’t want to be saddled with a language that’s been compromised to move work from the computer back into 0.0001 MHz human brains.
Re:Thirteen Years of Go by eweise on Friday November 11, 2022 @02:01PM (#33565147)
I tried the latest version of Java. Unfortunately, it still feels very clunky. They need to add the ability specify functions directly instead of as classes. ex: BiConsumer<T,U>
Re:Thirteen Years of Go by eweise on Friday November 11, 2022 @01:59PM (#33565106)
I prefer Kotlin as well. Its much more readable for expressing business problems.
Re:Thirteen Years of Go by origin_path on Friday November 11, 2022 @02:08PM (#33565234)
"Errors always get handled because the linter points them out and the devs don't cheat by setting up multi-function try/catch blocks"

My experience with Go has been that errors get "handled" by propagating them up the stack manually and then logging them, without keeping proper track of how the error got there. So there is error handling but only in theory, in practice what you get is a sort of hand-written stack unwinding logic with far worse functionality and consistency than exceptions, at 100x the verbosity.

Re:Thirteen Years of Go by throwawaygal7 on Friday November 11, 2022 @03:25PM (#33566322)
In go, you either handle the error where it happens or close to it, or log it. No need to pass things up just to log. I like the simplicity, and the zero cost at runtime. If you could handle the error in another lang you could handle it in go, or youd just supress or log it anyway.
Re:Thirteen Years of Go by erik_seaberg on Friday November 11, 2022 @04:27PM (#33567089)
In a microservice, there are very few errors that you don’t handle by doing nothing and returning the error to the caller. Retrying may be an option, but you have to be careful not to make your system into a cascading failure amplifier.
Re:Thirteen Years of Go by kaba0 on Friday November 11, 2022 @02:25PM (#33565490)
Error handling is strictly worse than pretty much any other language out there — you are only making you believe that you are handling your error cases. A pragmatic “handle it here or bubble it up” is a much better approach, as more often than not you can’t actually handle the error at call site.

Goroutines in themselves won’t give you actually correct concurrency.

I really hope that Go doesn’t replace Java.

Re:Thirteen Years of Go by smasher164 on Friday November 11, 2022 @02:35PM (#33565641)
> A pragmatic “handle it here or bubble it up” is a much better approach

This is exactly the approach used in Go code, so I'm not sure what you're referring to. If you're talking about the fact that you can technically ignore an error result like

    res, _ := doWork()
then that's a fair point. But we still have https://staticcheck.io/docs/checks#SA4006 for that.
Re:Thirteen Years of Go by kaba0 on Friday November 11, 2022 @04:48PM (#33567325)
I don’t see any automatic bubble up with Go.
Re:Thirteen Years of Go by smasher164 on Friday November 11, 2022 @09:06PM (#33569285)
I don’t think the original commenter said anything about “automatic”. That’s more of a subjective decision—whether or not you manually bubble up an error, or it just floats up because of the exception handler.

Empirically, java code has had terrible error handling, because people just stick one catch statement at the root of their program. Go atleast confronts you with the error at every step.

Re:Thirteen Years of Go by kaba0 on Saturday November 12, 2022 @04:21AM (#33571511)
And that is exactly the wrong approach. You really can’t do anything with the error case at most places. If I write a web server, which parts could knowingly handle a db connection error? Either the db driver internally, or going 10 deep higher and the request handler returning an 500 error.

In go you would just verbosely (and error pronely!!) have to manually bubble it up, while this is automatically happening in Java with an informative stack trace, with no option to forget about it. Java is the one that handles error cases properly (and that’s why you might see exceptions more there — because they weren’t silenced somewhere wrongly!) here.

Re:Thirteen Years of Go by smasher164 on Saturday November 12, 2022 @06:39PM (#33578373)
I agree that a stack trace is useful, but I disagree that automatic bubbling is universally good. If you look at well-written Go, context is added to every site where you bubble up an error.
Re:Thirteen Years of Go by ilyt on Friday November 11, 2022 @03:04PM (#33566068)
>Error handling is strictly worse than pretty much any other language out there — you are only making you believe that you are handling your error cases. A pragmatic “handle it here or bubble it up” is a much better approach, as more often than not you can’t actually handle the error at call site.

It could've definitely be better (just Rust-like Result<T> type would make it so much clearer to handle) but Go's insistence of dealing with it here and now means you have to think about what is exactly happening when it errors out, and are encouraged to add context to the error message instead of "here is stack trace, fuck you user, you're not worth knowing what is wrong".

But it's verboseness in common cases is inexcusable, if I have 3 steps to establish a connection, having 3 lines per error to handle is inexcusably bad. And it will be fucking 3 lines even if you write it in one line, because go fmt will expand it back to 3 lines

> Goroutines in themselves won’t give you actually correct concurrency.

Main advantage is they are cheap enough that doing goroutine per request won't bite you in most cases so you can have near-perfect parallelization of common apps by just writing essentially serial code.

The concurrency primitives are built into language and stdlibs which means when you do need synchronization, everyone does it same way.

Re:Thirteen Years of Go by Gwypaas on Friday November 11, 2022 @03:15PM (#33566207)
> The concurrency primitives are built into language and stdlibs which means when you do need synchronization, everyone does it same way.

As long as you after refactor N still are staying in the happy path avoiding the numerous footguns and implicit behavior Go supplies you with.

I would say if you stray outside a single thread or shared nothing fire up a Goroutine per response architecture deeply reconsider the choice of using Go.

https://www.uber.com/en-US/blog/data-race-patterns-in-go/

Re:Thirteen Years of Go by Xeoncross on Friday November 11, 2022 @04:45PM (#33567289)
> are encouraged to add context to the error message instead of "here is stack trace, fuck you user, you're not worth knowing what is wrong"

haha, so true. I almost always wrap errors at every level with addition context. If it was worth doing, then it's worth explaining.

People that prefer try/catching large sections of functionality or want to skip verbose handling of errors often have not thought through the user or tester experience. Heck, even trying to recreate the issue/state from production.

if err != nil { return err }

vs

if err != nil { return fmt.Errorf("context here: %s: %w", action_type, err) } (or wrapping some custom app error with context for the trace)

Of course you don't want to leak private details, but often there is a public component that is worth adding. This also brings up the concept of dual-error chains where what you log and what you report to the client are different.

Re:Thirteen Years of Go by kaba0 on Friday November 11, 2022 @05:02PM (#33567485)
You surely know that it is very common to rethrow the original exception wrapped in languages with try-catch — it still saves you the time to write that (plus it is safe, no code, plus stacktrace). It is still strictly better than whatever go has.
Re:Thirteen Years of Go by Xeoncross on Friday November 11, 2022 @06:02PM (#33568001)
I've written a lot of try/catch but no one in those languages do that for every branch, it's usually just everything wrapped in a big try/catch.

Go makes you deal with the error every single time something could go wrong, so you have a chance to do the right thing and append context at every single failure path.

Re:Thirteen Years of Go by kaba0 on Friday November 11, 2022 @09:01PM (#33569252)
Go makes you believe you dealt with the error, but instead you just forget about it.

Also, checked exceptions are very much not like that, and being able to handle errors of a logical unit is also beneficiary (e.g. transactions). You are free to use the scope-size that makes sense for the given use case.

Re:Thirteen Years of Go by Xeoncross on Saturday November 12, 2022 @04:05PM (#33577069)
> Go makes you believe you dealt with the error, but instead you just forget about it.

Can you explain that? Touching every context of an error propagation seems opposite of forgetting about it.

Re:Thirteen Years of Go by CoolCold on Saturday November 12, 2022 @01:51AM (#33570709)
> Go's insistence of dealing with it here and now means you have to think about what is exactly happening when it errors out

I read it as "let's stop pretending we are wizardy wizards and can do things right way in 100% cases and let the language to enforce us to handle errors, producing better result for average Joe SR SWE".

Am I right with my readings (i'm not a dev guy at all)?

Re:Thirteen Years of Go by Xeoncross on Sunday November 13, 2022 @02:06PM (#33586258)
Yes, every process a person/language/company/country/etc.. adopts has a cost. It's not free. The question is if being forced to always deal with errors is worth the cost of always dealing with errors.

I think it is. I will gladly trade a couple of hours of extra error handling code every week in exchange for no pager duty alarms on the weekend.

Re:Thirteen Years of Go by flippinburgers on Friday November 11, 2022 @08:25PM (#33569033)
It is good to be forced to recognize errors and manually send them up the stack. Too many programmers have a "not my problem" attitude about errors.

1. Immediately when the error occurs, send it to logging with all required data to find the exact point of failure + data to understand the "why".

2. Send the error up the stack.

If you do these two things, your systems written in golang will be resilient.

Re:Thirteen Years of Go by kaba0 on Friday November 11, 2022 @08:59PM (#33569242)
So rely on the programmer countering their laziness instead of having these things the default in the language also known as exceptions?
Re:Thirteen Years of Go by flippinburgers on Saturday November 12, 2022 @02:44AM (#33571002)
Exceptions are a nightmare.
Re:Thirteen Years of Go by kaba0 on Saturday November 12, 2022 @04:16AM (#33571483)
That’s your subjective opinion.
Re:Thirteen Years of Go by throwaway894345 on Friday November 11, 2022 @02:46PM (#33565785)
Not only that, but all of the features Go doesn't have means that you don't have to navigate the "which subset of the language does this project use?" problem. Every project uses pretty much the same language features. Similarly, the code formatter is universal and minimally configurable, so the code formatting looks the same across the ecosystem. Virtually everyone uses the same test runner too. Also, you get documentation (including links to third party and standard library packages!) for free--no need to set up a CI pipeline for publishing documentation packages. Same with package hosting--no need to set up a CI pipeline to publish packages.

There's a ton of this kind of stuff that amounts to a whole lot of productivity that gets overlooked in all of the pennywise-pound-foolish type-system navel-gazing that programmers fixate on.

Re:Thirteen Years of Go by HillRat on Friday November 11, 2022 @03:17PM (#33566233)
One of my mantras is "what you say no to is more important than what you say yes to," and the Go team says no to a lot. It can be frustrating and Go can be incredibly inexpressive (and, frankly, boring) compared to other languages, but it's hard to find another stack in which any random developer can be as productive as quickly on any random codebase. There are other languages where my personal velocity is a lot higher, but at a team level I haven't found anything that beats Go.
Re:Thirteen Years of Go by Xeoncross on Friday November 11, 2022 @03:02PM (#33566050)
"Gofmt’s style is no one’s favorite, yet gofmt is everyone’s favorite" - https://www.youtube.com/watch?v=PAAkCSZUG1c&t=8m43s
Re:Thirteen Years of Go by avgcorrection on Friday November 11, 2022 @04:18PM (#33566998)
> I don't want it to win over Rust though, Rust is awesome.

Why even perpetuate this red herring comparison—maybe over a decade old?—by making unprompted mentions of Rust though.

Re:Thirteen Years of Go by Ferret7446 on Friday November 11, 2022 @08:59PM (#33569247)
Many of those things are a consequence of the language, or at least the philosophy behind the language.

e.g., tooling is good because the language is easy to parse