3 ms·
There's a balance. Reading golang code is very burdensome because the reader has to read many lines of code which can amount to nothing more than a map/filter/r
by azth 5y ago
There's a balance. Reading golang code is very burdensome because the reader has to read many lines of code which can amount to nothing more than a map/filter/reduce, and those are littered everywhere. Same with error handling, which is pervasive and distracts from what the code is trying to do.
Obviously, it can be taken too far as with the case of C++, but golang is in the opposite extreme where a lot of code does very little and is not clear what it's doing.
> and you can spend your cognitive load on the genuine complexity of your problem
Which is what a good language lets you do. In golang, a lot of time and cognitive load is spent trying to express your ideas in very unsafe and verbose manners.
- philosopher1234 5y ago>Reading golang code is very burdensome because the reader has to read many lines of code which can amount to nothing more than a map/filter/reduce, and those are littered everywhere. I think my problem is that this simply doesn't match my real life experience. In reality, the Java code (which is the majority at my company) is much more likely to overabstract and thus be very challenging to read than the go code I interact with. So, while your argument is compelling at a distance, it seems to me it must be flawed as it simply doesn't match my experience. I would suggest the flaw might be something like number of lines of code not being equivalent to reading difficulty. Like, yes go code hasa more lines dedicated to if err != nil {}, but those lines are low density and easy to scan. Its a bit like reading light fiction as opposed to Dostoyevsky.
- azth 5y agoThere's no reason to have to write overly abstract code in Java. Modern Java has many features that let you write even more clear code (e.g. interfaces with default methods). Even things like mocking, you don't need to write a dedicated interface, unlike golang, which clutters up the code base and makes it difficult to follow. As for error handling, compare var res = foo(bar(), baz()); and f, err := bar() if err != nil { return err } b, err := baz() if err != nil { return err } res, err := foo(f, b) if err != nil { return err } It's much harder to follow what's going on. Now add more complex code (e.g. code that does validation or something and you'll see how it blows up) var res = foo(items.map(i -> i.validate()), bar()); and validatedItems := make([]Item, len(items) for i, item := range items { var err error validatedItems[i], err = item.Validate() if err != nil { return err } } f, err := foo() if err != nil { return err } res, err := foo(validatedItems, f) if err != nil { return err } 1 line maps to over 15 lines, I don't think that's readable.
- Mawr 5y ago> There's no reason to have to write overly abstract code in Java. Whether that's true is beyond the point, which is that the majority of Java code out there is in fact overabstracted. That should serve as a hint that there may just be something about Java that does lead to overabstraction. > As for error handling, compare [...] It's much harder to follow what's going on. Making error-handling code paths happen implicitly in the background isn't a straight win. For example, you lose the ability to tell a fallible function from a non-fallible one, especially at the point of calling it. Overall, I find that being able to see all code paths explicitly laid out is better, Go syntax aside. Keep in mind that these examples are tiny, and therefore it's trivial to see how exceptions would implicitly propagate. They become much harder to track as the size and complexity of a codebase grows. > Now add more complex code (e.g. code that does validation or something and you'll see how it blows up) [...] 1 line maps to over 15 lines, I don't think that's readable. I wouldn't say the amount of lines is a great indicator of readability, not unless the difference was in the ballpark of maybe 1 to 100. --- I don't think this code sample is representative: - what would happen to this pretty one-liner if I wanted to catch the exception raised in `i.validate()` and raise a different exception instead? - you can create the .map() function in Go too - the Go code size will not grow linearly as you add more .map()/.filter() calls I feel like a good example of Java code would be much denser, leveraging several expressive language features that Go doesn't have.