7 ms·
I've found that there are only two reasons I like Go: 1) It's concurrency model was a revelation compared to anything I did in the C world. 2) It's opinionated.
by struct 11y ago
I've found that there are only two reasons I like Go:
1) It's concurrency model was a revelation compared to anything I did in the C world.
2) It's opinionated.
Everything else is a bonus. In Go, there's only one way to format your program correctly, there's only one way to document your program correctly, there's only one recommended way to serialize to JSON, it only has one (IMO really awesome package management system) etc. It's remarkable how little thought I now need to put into those things.
- threeseed 11y agoEvery programming language starts out like that though. It's just that over time needs/requirements change and then suddenly you have another package manager, another JSON parsing library etc.
- generic_user 11y agoAs a counter argument I would point to C, C++ and Lua as examples of languages that try to keep a basic generic standard library and let everything else fall out in third party libraries. I consider Go more in line with the C family then with the scripting languages like Python etc, With a slightly bigger stdlib.
- iofj 11y agoI disagree strongly. You should keep into account that Go is a very young language, and hasn't had to deal with historical baggage. It's still the hot new thing, and that just won't last. 1) Concurrency model : there are plenty of C++ frameworks doing various concurrency models. As long as you do what Go does, and only use that framework, no linking to other stuff, it works beautifully. Already, the standard library is making allowances for other synchronization primitives (look at the sync package) Of course, in C++, you'll be sorely tempted to link in code with other concurrency primitives. Especially when it comes to having 2 kinds of event loops, you really shouldn't do that. It doesn't help that a lot of large companies felt the need for 2-3 proprietary C++ event loop systems. Fortunately, most libraries aren't parallelized, so it doesn't really matter what event loop system you run them under. Also, from working with other concurrency models ... I miss a lot of stuff. Futures ... oh my God, does Go need that (why doesn't "go func()" return a future ? AARGH). Limiting resources for specific functions like java's executor framework ... when you need it, there's no going without it.' Also, select is a horrible way to implement protocols (rules-based communication between either different parts of the same process or simply other parts of a distributed system). Implementing a protocol as a set of methods that can be called on a given object, with or without remote object references works much better. Incidentally, this is what all Go protocol libraries do (google protobuf, cap'n proto, flatbuffers, ...). I understand why they choose this approach over the "native" Go approach : select isn't useful for anything but the most basic of protocols. If you have more than 2-3 message types ... things start to get completely out of hand with select. 2) only one way to format your program correctly ? I think you'll find that gofmt in fact leaves many questions unanswered. Line break or no ? Up to you. Where ? Up to you. Full syntax for struct initializers or short syntax ? Up to you, gofmt won't change it ... What I will credit gofmt with is popularizing the concept, and getting code formatters much more opinionated in other languages, and that is a very good thing. But LLVM's C++ formatter and autopep8 are superior in functionality to gofmt for their respective languages. 3) I have seen at least 5 different JSON serialization libraries in Go. There's 3 broad approaches. You can either use reflection on structs and then use that to decode JSON. Trouble is, this is slow ... very very slow. It's as slow as the next option, but doing things this way does mostly ensure correctness (doesn't deal with various kinds of ddos though). There's just "decoding" JSON into map[string]interface{}, which is about as fast but it can deal with fields unknown at compile time, which can be important if you're making something that, say, just checks one aspect of requests (e.g. security, or load balancing). The huge disadvantage is casting interface{} to what you need every time. And finally there's precompiling a given JSON format into a Go library, which is a LOT faster than either of the previous approaches (but also can't deal with unknown fields). 4) Package management ... lacks versioning. There's no guarantee your code will compile 6 months later if you use Go's own package management. In fact, given just how in flux everything still is, it's pretty much guaranteed to not even compile. Also, a number of Go advantages are only advantages because Go is only beginning to exit it's honeymoon phase. Go libraries, whether builtin or on github, are "v1" designs : they're consistent, they don't have historical crap in them, they don't have 20 unforeseen but necessary usecases crammed in in extremely uncomfortable ways. Not yet, that is : the honeymoon is ending. Bad design decisions do bite larger programs on occasion (such as Go's logging not using an interface, which can bite you, leaving you with little choice but to reimplement logging for your project/company). This means that while things are pretty good now when it comes to the standard library and most github libraries, they're getting worse fast. Go libraries are written by enthousiasts mostly at the moment. So while ignoring errors occurs regularly in those libraries, it's not yet like C, where every single error is ignored in the vast majority of libraries.
- jacques_chester 11y ago> such as Go's logging not using an interface, which can bite you, leaving you with little choice but to reimplement logging for your project/company Ah yes, another pet peeve. The Go standard library sometimes uses package functions, sometimes a struct with functions and then -- sometimes, not always -- has an interface that goes with that struct. Whenever you have a library with the interface, you can fake it out for testing. When it hands back a physical struct, you wind up wrapping it. Any time you wander into a repo drop from a company, you'll find standard lib wrappers, all written from scratch, because of this. Golang interfaces are a strong feature of the language and they make it possible to practice more isolated unit testing. The inconsistency across the standard lib is very frustrating. Frankly I'd rather be stuck with no interfaces than the mishmash I faced. I wanted to like Go. I really, really did.
- ansible 11y agoBut LLVM's C++ formatter and autopep8 are superior in functionality to gofmt for their respective languages. I was under the impression that some of the syntax for C++ and / or C is a bit ambiguous, which makes it difficult to parse correctly, and to make source code transformations that will absolutely, positively not change the semantics of the code. At any rate, getting more or less the entire community onboard with using one particular code formatter is the really hard part. I'd say it is impossible to do with existing languages. I don't see how the majority of in-production C++ code, or Python code will ever be formatted in one fixed style. So even if superior formatters exist in those languages, it doesn't matter, because the majority of code I will encounter out in the wild (open source or not) will not be formatted in with a single convention. If there is one lasting legacy from the creation of golang, it is hope that for all new languages, their communities will adopt a single code formatting convention. I hope that everyone, whether or not they like golang itself, sees how important that is moving forward.
- coldtea 11y ago>I was under the impression that some of the syntax for C++ and / or C is a bit ambiguous, which makes it difficult to parse correctly, and to make source code transformations that will absolutely, positively not change the semantics of the code. That's for naive parsing of C++, like some do for syntax highlighting etc -- not for LLVM's C++ formatter, which uses the AST of the fully blown C++ compiler et al. If that parser didn't get everything right, then LLVM's C++ output will also be borked, not just the formatter.
- lmm 11y agoYou owe it to yourself to at least try a modern, strongly typed functional language (Ocaml, Haskell, F# or Scala). If you go far enough that you understand the advantages of such languages, and still decide they're not for you, then fair enough. But there's a whole world out there and it's incredibly frustrating to see people talk as though Go is the best language when they don't seem to even know what the possibilities are.
- fromMars 11y agoI loved working with F# for windows development but it wasn't a viable option for most of my projects. Ocaml is also a great language but it had problems with poor standard libraries and concurrency support. I consider Haskell a beautiful language, but the most challenging for me to reason about and understand. Scala has always seemed like an abomination to me, but I haven't used it enough. I now use Go for most of my professional projects. It is just simpler than the languages you listed. The learning curve is smaller, and, I am typically working on projects with other programmers, most who have never used a functional language and many are openly hostile to that paradigm. Also, most of the projects I work on don't need the more power features of functional languages. If the project's complexity is high, for instance, a derivative pricing library, or if I am working with a small team with previous experience with functional languages, or doing a personal project, then I would consider using a different tool.