5 ms·
I firmly believe that the only reason golang gained traction and got to the point where it is today is that it had the Google branding behind it. As you point
by azth 5y ago
I firmly believe that the only reason golang gained traction and got to the point where it is today is that it had the Google branding behind it.
As you point out, its design philosophy is overly simplistic to the point of being almost naive. Complexity exists in the real world, there's no getting away from it, and if you keep your language deliberately "simple", you are pushing complexity to the user.
I wouldn't even say golang looks like Java. Java has evolved quite significantly in the past few years, adding many useful features that further aid in program modeling ability and expressiveness, like records and pattern matching. Not to mention it getting green threads that are going to be better implemented than golang's "goroutines" by virtue of having structured concurrency built in from the start.
- philosopher1234 5y agoHow is the design too simple? Why is complexity better?
- azth 5y agoGolang is anemic when it comes to modeling ability and expressiveness. I have come across so many code sections where having something like sealed classes and pattern matching or switch expressions would have made code so much readable and safer. The world is complex, it's just reality. The question becomes where do you want to push that complexity, on the user or on the language? golang decides the former, which is why you end up with messes like the kubernetes code base.
- philosopher1234 5y ago>Golang is anemic when it comes to modeling ability and expressiveness. I have come across so many code sections where having something like sealed classes and pattern matching or switch expressions would have made code so much readable and safer. But there is a tradeoff. Every complex feature you add has a continuous cost applied to every reader, in that they have to become expert with the new feature. C++ is a great example of the failure mode here, and even Java has too many features such that using many of them will confuse most of my coworkers. Having few features means that the code is more accessible, and you can spend your cognitive load on the genuine complexity of your problem rather than fiddling with language knobs.
- azth 5y agoThere'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.
- zozbot234 5y agoThere's plenty of "surprise" complexity hidden in the Golang stdlib. https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-... It's kind of a necessary evil (though I guess it should be better documented, so users are less likely to bitten by it) because Go does not have good ways of expressing complexity in interfaces. This is exactly how enforced "simplicity" can backfire in practice.
- philosopher1234 5y agoBut this is a good thing not a bad thing. The mistake in that article is thinking that the existence of surprising edge cases means the whole design was a mistake. Its better to design for the 99% not the 1%. I don't want to live in Amos' perfectionist world.
- zozbot234 5y agoIt is a mistake when the "1% of the time" edge cases are "surprising"; it's not a problem if they aren't, because the interface accounts for them properly. "Surprising edge-cases" in general is a recipe for very hard to debug software defects.
- philosopher1234 5y agoI think I disagree. I think its ok to make the 1% use case require extra work to debug (it was probably hard anyways) rather than making the 99% pay a tax on every use of the API to save them. But this is perhaps also where the question becomes more of a question of values and use cases than something generalizable. I don't think Go is the ideal language for writing code that demandingly low-level.
- Yoric 5y agoInteresting. I come from the opposite point of view, i.e. that surprising behavior should be avoided like the plague, using combinations of type-checking or linting or dynamic detection (in debug builds). I wonder why our points of view on this are so different. May I ask what your background is? Perhaps you come from more dynamic languages than I do? Until a few years ago, I used to write C++ and JavaScript for a living and OCaml for fun.