Comment by TheDong

4 days ago

The mutex case is one where they're using a mutex to guard read/writes to a map.

Please show us how to write that cleanly with channels, since clearly you understand channels better than the author.

I think the golang stdlib authors could use some help too, since they prefer mutexes for basically everything (look at sync.Map, it doesn't spin off a goroutine to handle read/write requests on channels, it uses a mutex).

In fact, almost every major go project seems to end up tending towards mutexes because channels are both incredibly slow, and worse for modeling some types of problems.

... I'll also point out that channels don't save you from data-races necessarily. In rust, passing a value over a channel moves ownership, so the writer can no longer access it. In go, it's incredibly easy to write data-races still, like for example the following is likely to be a data-race:

    handleItemChannel <- item
    slog.Debug("wrote item", "item", item) // <-- probably races because 'item' ownership should have been passed along.

For that last example, if 'item' is immutable, there is no issue, correct?

  • Yeah, indeed.

    Developers have a bad habit of adding mutable fields to plain old data objects in Go though, so even if it's immutable now, it's now easy for a developer to create a race down the line. There's no way to indicate that something must be immutability at compile-time, so the compiler won't help you there.

    • Good points. I have also heard others say the same in the past regarding Go. I know very little about Go or its language development, however.

      I wonder if Go could easily add some features regarding that. There are different ways to go about it. 'final' in Java is different from 'const' in C++, for example, and Rust has borrow checking and 'const'. I think the language developers of the OCaml language has experimented with something inspired by Rust regarding concurrency.

      3 replies →