4 ms·
In the first one, he complains that one character is enough to cause an issue, but the user should really have a good understanding of variable scope and the di
by __loam 11mo ago
In the first one, he complains that one character is enough to cause an issue, but the user should really have a good understanding of variable scope and the difference between assignment and instsntiation if they're writing concurrent go code. Some ides warn the user when they do this with a different color.
Races with mutexes can indicate the author either doesn't understand or refuses to engage with Go's message based concurrency model. You can use mutexes but I believe a lot of these races can be properly avoided using some of the techniques discussed in the go programming language book.
- konart 11mo ago>he complains that one character is enough He complains that language design offers no way of avoiding it (in this particular case) and relies only on human or ide. Humans are not perfect and should not be a requirement to write good code.
- xlii 11mo agoWhatever the case Go's tooling (i.e. IDE part) is one of the best in class and I think it shouldn't be be dismissed in the context of some footguns that Go has.
- TheDong 11mo ago"best in class"? I feel like Java's IDE support is best in class. I feel like go is firmly below average. Like, Java has great tooling for attaching a debugger, including to running processes, and stepping through code, adding conditional breakpoints, poking through the stack at any given moment. Most Go developers seem to still be stuck in println debugging land, akin to what you get in C. The gopls language server generally takes noticeably more memory and cpu than my IDE requires for a similarly sized java project, and Go has various IDE features that work way slower (like "find implementations of this interface"). The JVM has all sorts of great knobs and features to help you understand memory usage and tune performance, while Go doesn't even have a "go build -debug" vs "go build -release" to turn on and off optimizations, so even in your fast iteration loop, go is making production builds (since that's the only option), and they also can't add any slow optimizations because that would slow down everyone's default build times. All the other sane compilers I know let you do a slower release build to get more performance. The Go compiler doesn't emit warnings, insisting that you instead run a separate tool (govet), but since it's a separate tool you now have to effectively compile the code twice just to get your compiler warnings, making it slower than if the compiler just emit warnings. Go's cgo tooling is also far from best in class, with even nodejs and ruby having better support for linking to C libraries in my opinion. Like, it's incredibly impressive that Go managed to re-invent so many wheels so well, but they managed to reach the point where things are bearable, not "best in class". I think the only two languages that achieved actually good IDE tooling are elisp and smalltalk, kinda a shame that they're both unserious languages.
- rustystump 11mo agoJava best in class? I love java. It is my first love but ill take go ecosystem 1000% of the time.
- TheDong 11mo agoMind explaining your debugging setup, i.e. which IDE you use and what tooling you use to be able to step through and reason about code?
- gf000 11mo agoIt absolutely is. There is not many ecosystems where you can attach a debugger to a live prod system with minimal overhead, or one that has something like flight recorder, visualvm, etc.
- Mawr 11mo ago> The gopls language server generally takes noticeably more memory and cpu than my IDE requires for a similarly sized java project Okay, come on now :D Absolutely everything around Java consumes gigabytes of memory. The culture of wastefulness is real. The Go vs Java plugins for VSCode are no comparison in terms of RAM usage. I don't know how much the Go plugin uses, which is how it should be for all software — means usage is low enough I never had to worry about it. Meanwhile, my small Java projects get OOM killed all the time during what I assume is the compilation the plugin does in the background? We're talking several gigabytes of RAM being used for... ??? I'm not exactly surprised, I've yet to see Java software that didn't demand gigabytes as a baseline. InteliJ is no different btw, asinine startup times during which RAM usage baloons.
- gf000 11mo agoJava consumes memory because collecting garbage is extra work and under most circumstances it makes no sense to rush it. Meanwhile Go will rather take time away from your code to collect garbage, decreasing throughput. If there is ample memory available, why waste energy on that? Nonetheless, it's absolutely trivial to set a single parameter to limit memory usage and Java's GCs being absolute beasts, they will have no problem operating more often. Also, intellij is a whole IDE that caches all your code in AST form for fast lookoup and stuff like that.. it has to use some extra memory by definition (though it's also configurable if you really want to, but it's a classic space vs time tradeoff again).
- TheDong 11mo agoThe 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.
- questioner8216 11mo agoFor that last example, if 'item' is immutable, there is no issue, correct?
- TheDong 11mo agoYeah, 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.
- questioner8216 11mo agoGood 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.
- beeb 11mo agoI would argue it doesn't help that all errors are usually named `err` and sprinkled every third line of code in Go. It's an easy mistake to make to assign to an existing variable instead of create a new variable, especially if you frequently switch between languages (which might not have the `:=` operator).