4 ms·
Judging by the examples, the Go code is easier to read, write and maintain.
by xyproto 4y ago
Judging by the examples, the Go code is easier to read, write and maintain.
- ivolimmen 4y agoWell as someone that has been developing software in Java for 20 years and never touched Go; it's the other way around.
- Cthulhu_ 4y agoCan you elaborate? I mean there may be some new operators and concepts in the Go versions, but they're explained succinctly in https://go.dev/tour/ https://go.dev/tour/
- kaba0 4y agoJava is a similarly small language, with perhaps even less of a learning curve.
- doctor_eval 4y agoI developed and maintained Java software professionally for over 20 years, since 1.0, but now I work in Go. There is no way I’d willingly go back to Java, and these examples really underscore some of the reasons. I do however wonder, now, what I’m missing out on with other languages, particularly swift and rust.
- bsaul 4y agoSwift has great support for enums (and ADT in general). That's about the only thing i miss when i switch from swift to go. Generics and protocol oriented programming is nice, but the ergonomics makes it still not that enjoyable (you start banging your head against walls pretty quickly beyond the most simple examples).
- kaba0 4y agoRust has a great, Haskell-inspired way to create algebraic data structures (with the enum keyword). These same structures can be very nicely destructured and pattern matched on.
- threeseed 4y agoThat's more to do with your preferences. For me Golang has far weaker and less flexible error handling semantics. And concurrency is more verbose in Java but it's easy enough to abstract it behind a wrapper. Where as you can't escape Golang's error handling.
- Cthulhu_ 4y agoOf course, you have to consider whether you SHOULD escape it. I do believe you probably have more control over Java's threads, making them a bit more verbose. But, both Java itself - as you mention - and languages built on top of the JVM have ways to make it less verbose.
- shp0ngle 4y agoWell, that's because goroutines and channels are something, that's first class in go and has a special syntax. While in Java, it tries to mostly keep the existing Java syntax. I guess people that write Java are used to a lot of "lasagna" all-is-object boilerplate and ignore it. The same way go people are used to ignore the `err != nil` lines everywhere.
- sdevonoes 4y agoJudging by the examples, when it comes to code that deals with concurrency both Go and Java are difficult to maintain. Plenty of times I have dealt with "clever code" (written by others and by my past self) that works 99% of the time.
- pron 4y agoThe examples translate Go idioms directly to Java code rather than using Java idioms; you wouldn't normally write Java like Go any more than you'd write Go like Java. They also make use of constructs that are overkill for such simple examples. For example, the first example could be written as: Thread.startVirtualThread(() -> say("world")); say("hello"); which would also replicate same concurrency bug as in the original Go program (the Java example, as written, does not have that bug, but neither would var t = Thread.startVirtualThread(() -> say("world")); say("hello"); t.join(); ). Go makes certain concurrency bugs easy to introduce and hard to find, while Java helps avoid them, but that is also not easy to see from these particular examples.
- emccue 4y agoYeah, sorry. I would have used .startVirtualThread more if I wasn't under the impression that I needed to do Thread.currentThread().interrupt() when catching and re-throwing as a RuntimeException. So I was choosing between the noise of that in the examples and the noise of the executor + submit with a lambda that returned null.
- dhab 4y agoAfter mulling between Elixir vs Go to have a tool in the toolbelt covering the use-case of concurrent server-side apps, I picked a book on Go and went through the first chapter. Disenchanted to hear (some) concurrency bugs easy to introduce and hard to find in Go. Could someone mention how does this compare to Elixir?
- xyproto 4y agoIt all depends on what you're trying to do. These cases work flawlessly in Go, in my experience: * Batch 10 tasks and run them concurrently (using WaitGroups). * Locking resources while reading and writing with a mutex like sync.RWMutex, using .Lock() and .Unlock(), often together with defer. * Locking resources while only reading with a sync.RWMutex, using .RLock() and .RUnlock(), often together with defer. * Running code "in the background" with goroutines, ie. go func() { <code goes here> }(). * Detecting race conditions by building with go build -race and then running the program. However, when using channels, select, closing channels, waiting on channels in a for loop etc, things can easily become more subtle. On a general basis, I disagree that concurrency bugs are easy to introduce and hard to find in Go. However, pure functional programming languages like Haskell, with little state, will always have the upper hand when it comes to concurrency. See also: https://gobyexample.com/waitgroups https://gobyexample.com/waitgroups https://gobyexample.com/mutexes https://gobyexample.com/mutexes https://gobyexample.com/defer https://gobyexample.com/defer https://gobyexample.com/goroutines https://gobyexample.com/goroutines https://gobyexample.com/non-blocking-channel-operations https://gobyexample.com/non-blocking-channel-operations