News for hackers. Stuff that matters.
Re:Thoughts on Go vs. Rust vs. Zig by Rikudou on Thursday December 04, 2025 @06:17PM (#46154599)
I think the Go part is missing a pretty important thing: the easiest concurrency model there is. Goroutines are one of the biggest reasons I even started with Go.
Re:Thoughts on Go vs. Rust vs. Zig by auxiliarymoose on Thursday December 04, 2025 @06:47PM (#46154929)
Agreed. Rob Pike presented a good talk "Concurrency is not Parallelism" which explains the motivations behind Go's concurrency model: https://youtu.be/oV9rvDllKEg

Between the lack of "colored functions" and the simplicity of communicating with channels, I keep surprising myself with how (relatively) quick and easy it is to develop concurrent systems with correct behavior in Go.

Re:Thoughts on Go vs. Rust vs. Zig by PaulKeeble on Thursday December 04, 2025 @07:17PM (#46155204)
Its a bit messy to do parallelism with it but it still works and its a consistent pattern and their are libraries that add it for the processing of slices and such. It could be made easier IMO, they are trying to dissuade its use but its actually really common to want to process N things distributed across multiple CPUs nowadays.
Re:Thoughts on Go vs. Rust vs. Zig by silisili on Thursday December 04, 2025 @07:37PM (#46155376)
True. But in my experience, the pattern of just using short lived goroutines via errgroup or a channel based semaphore, will typically get you full utilization across all cores assuming your limit is high enough.

Perhaps less guaranteed in patterns that feed a fixed limited number of long running goroutines.

Re:Thoughts on Go vs. Rust vs. Zig by theshrike79 on Friday December 05, 2025 @03:10AM (#46157925)
Just the fact that you can prototype with a direct solution and then just pretty much slap on concurrency by wrapping it in "go" and adding channels is amazing.
Re:Thoughts on Go vs. Rust vs. Zig by macintux on Thursday December 04, 2025 @08:07PM (#46155633)
> the easiest concurrency model there is

Erlang programmers might disagree with you there.

Re:Thoughts on Go vs. Rust vs. Zig by kibwen on Thursday December 04, 2025 @09:04PM (#46156044)
Erlang is great for distributed systems. But my bugbear is when people look at how distributed systems are inherently parallel, and then look at a would-be concurrent program and go, "I know, I'll make my program concurrent by making it into a distributed system".

But distributed systems are hard. If your system isn't inherently distributed, then don't rush towards a model of concurrency that emulates a distributed system. For anything on a single machine, prefer structured concurrency.

Re:Thoughts on Go vs. Rust vs. Zig by throwawaymaths on Thursday December 04, 2025 @09:46PM (#46156313)
have you ever deployed an erlamg system?

the biggest bugbear for concurrent systems is mutable shared data. by inherently being distributable you basically "give up on that" so for concurrent erlang systems you ~mostly don't even try.

if for no other reason than that erlang is saner than go for concurrency

like goroutines aren't inherently cancellable, so you see go programmers build out the kludgey context to handle those situations and debugging can get very tricky

Re:Thoughts on Go vs. Rust vs. Zig by kibwen on Thursday December 04, 2025 @09:01PM (#46156020)
I'll disagree with you there. Structured concurrency is the easiest concurrency model there is: https://vorpus.org/blog/notes-on-structured-concurrency-or-g...
Re:Thoughts on Go vs. Rust vs. Zig by auxiliarymoose on Thursday December 04, 2025 @11:24PM (#46156826)
But how does one communicate and synchronize between tasks with structured concurrency?

Consider a server handling transactional requests, which submit jobs and get results from various background workers, which broadcast change events to remote observers.

This is straightforward to set up with channels in Go. But I haven't seen an example of this type of workload using structured concurrency.

Re:Thoughts on Go vs. Rust vs. Zig by yxhuvud on Friday December 05, 2025 @02:06AM (#46157589)
The point of structured concurrency is that if you need to do that in code, then there is a need of a predefined structured way to do that. Safely, without running with scissors like how channel usage tend to be.
Re:Thoughts on Go vs. Rust vs. Zig by kristianp on Friday December 05, 2025 @02:09AM (#46157606)
It would be good to see an example of what that looks like.
Re:Thoughts on Go vs. Rust vs. Zig by auxiliarymoose on Friday December 05, 2025 @02:33AM (#46157711)
But how does one actually do that? What does the architecture and code look like?
Re:Thoughts on Go vs. Rust vs. Zig by pornel on Friday December 05, 2025 @07:50AM (#46160585)
You do the same thing, if that's really the architecture you need.

Channels communicating between persistent workers are fine when you need decoupled asynchronous operation like that. However, channels and detached coroutines are less appropriate in a bunch of other situations, like fork-join, data parallelism, cancellation of task trees, etc. You can still do it, but you're responsible for adding that structure, and ensuring you don't forget to wait for something, don't forget to cancel something.

Re:Thoughts on Go vs. Rust vs. Zig by auxiliarymoose on Friday December 05, 2025 @06:03PM (#46168554)
You can accomplish fork-join, data parallelism, and cancellation of task trees in a with `errgroup` in Go (which provides a way to approach structured concurrency).

So at least those are a subset of Go's concurrency model.

Re:Thoughts on Go vs. Rust vs. Zig by pornel on Friday December 05, 2025 @08:28PM (#46169660)
> So at least those are a subset of Go's concurrency model.

That's why the article about structured concurrency compared it to goto. Everything is a subset of goto. It can do everything that structured programming can do, and more! With goto you can implement your own conditions, switches, loops, and everything else.

The problem is not the lack of power, but lack of enforced structure. You can implement fork-join, but an idiomatic golang implementation won't stop you from forking and forgetting to join.

Another aspect of it is not really technical, but conventions that fell out of what the language offers. It's just way more common to DIY something custom from a couple of channels, even if it could be done with some pre-defined standard pattern. To me, this makes understanding behavior of golang programs harder, because instead of seeing something I already know, like list.par_iter().map().collect(), I need to recognize such behavior across a larger block of code, and think twice whether each channel-goroutine dance properly handles cancellations, thread pool limits, recursive dependencies, is everything is correctly read-only/atomic/locked, and so on.

Re:Thoughts on Go vs. Rust vs. Zig by Zambyte on Friday December 05, 2025 @12:08AM (#46157029)
The new (unreleased right now, in the nightly builds) std.Io interface in Zig maps quite nicely to the concurrency constructs in Go. The go keyword maps to std.Io.async to run a function asynchronously. Channels map to the std.Io.Queue data structure. The select keyword maps to the std.Io.select function.
Re:Thoughts on Go vs. Rust vs. Zig by maherbeg on Friday December 05, 2025 @01:04PM (#46164893)
One other thing I think it misses, is how easy it is to navigate a massive code base because everything looks the same. In a large team, this is crucial and I value the legibility over cleverness (I really dislike meta programming).

Really the only thing I found difficult is finding the concrete implementation of an interface when the interface is defined close to where it is, and when interfaces are duplicated everywhere.