15 ms·
Go is not a simple language. Please learn from my mistakes, and ignore arbitrary metrics like how go has fewer keywords. The complexity doesn't go away, it's hi
by preommr 6y ago
Go is not a simple language. Please learn from my mistakes, and ignore arbitrary metrics like how go has fewer keywords. The complexity doesn't go away, it's hidden away somewhere.
If anybody wants to learn go, ignore everything about how easy it is to learn. Because it's extremely deceptive. Take time to actually read through a lot of the important underlying concepts like how slices work.
Ignore comments about how go is simple to write. There's a fair amount of bad go code and people break rules all the time. From official sdks to standard libs. Go can be extremely difficult to both write and read. It's implicit interfaces and judicious abuse of interface{} can make tracing how a library is supposed to work a PITA. Writing go can be difficult because of a lack of some language constructs that leave you unsure how to proceed.
If you can, use goland. I use vscode and it's... not pretty. Almost every single thread I've seen on reddit recommends goland. My experience with vscode has been very unpleasant, particularly with go plus.
OTOH, things like criticisms about it's error handling are overblown. At best it's a mild nuisance, and more often than not, a good thing that makes error handling explicit and clear.
There are many things about go that have made me appreciate it's existence. There are also many things that have left me absolutely baffled at how bad it is.
- randomdata 6y ago> Ignore comments about how go is simple to write. Do people say that? I've never heard anyone claim that Go is simple to write. Pike, I believe (may have been someone else), claimed something to the effect that new grads with limited exposure to real-world codebases were able to understand existing projects written in Go more quickly than in other languages at Google. I have seen that message distilled down into "Go is simple to read." Go was built on the premise that people spend more time reading code than writing code and Go attempts to make tradeoffs towards reading optimization rather than writing optimization. Whether or not it is successful in that is another topic for another day.
- Thaxll 6y agoGo is very simple to read and to write, I'm not sure how one can argue against that. Without prior knowledge you can jump into any code base and won't be suprised by something you never seen before or does not understand what it does. The language is simple to grasp because it has just a few concepts and keywords.
- egeozcan 6y agoyou cannot write a generic function that returns a modified slice without losing types. that, in my book, means hard to write. ...which makes it also very easy to read.
- Thaxll 6y agoThen you write 2 functions, what you're talking about is a different question.
- adkadskhj 6y agoMaybe. If you have to remember two functions to _understand_ the code, is reading really easier? I imagine reading implies understanding, and while i definitely think Go is easier to read without understanding, i don't think that's the real implication.
- egeozcan 6y agoif having to write a separate function for each type of container is easy for you, then I can only respectfully disagree :) I'm saying this as someone who is learning go for fun.
- hnlmorg 6y agoI don't see the point of cherry picking highly specific examples because for every argument there will be just as many counterarguments from other domains. To be more specific: the point isn't whether Go is "always" simpler to write but whether it is generally simpler to write. I think the latter is true for all the domains I've written code in Go and I've solved some pretty hard problems in Go (check out my Github repositories if you don't believe me). The awesome thing about programming languages is that you're free to pick another language if that is a better fit for any specific domain or even personal preference. Hence why I've worked in more than a dozen different programming languages over the years. So rather than moaning that Go doesn't fit a particular pattern where you need to rely on generics, perhaps use a language that has generics to solve that problem and save Go for the occasions you don't need generics (which, if we're all honest, isn't something we need to rely on half as much as people claim when moaning about the lack of features in Go). As a veteran developer, what really annoys me the most is people who pick a language that isn't well suited for solving the problem at hand and then moan that language needs to change, rather than developers picking the right tools for the job. I'd rather see a language lack features but focuses to serves its core demographic well than see everything and the kitchen sink is thrown at it and everyone using it even when they know they shouldn't simply because they're too afraid to learn anything new. What we need is more appreciation that "general purpose languages" doesn't mean "should be used to do practically anything in". Then I'd think we'd all get along better.
- adkadskhj 6y ago> I have seen that message distilled down into "Go is simple to read." I think the two are related, directly. However in my experience i don't even agree with Pike. Go is not easy to read. Yes, a single small function in Go is much easier to read (perhaps) than X lang. However Go requires a huge (brain)memory table to remember everything, because it spreads logic out. So you have to remember X function, scroll up, look at Y function remembering how it interacts with X, etcetc. > Whether or not it is successful in that is another topic for another day. I guess i bikeshedded, sorry :s
- rob74 6y ago> Pike, I believe [...], claimed something to the effect that new grads with limited exposure to real-world codebases were able to understand existing projects written in Go more quickly than in other languages at Google. I have seen that message distilled down into "Go is simple to read." Yeah, it was Pike, and I have also seen it distilled (in bad faith) into "Go is a primitive language for inexperienced programmers, so it's beneath me to touch it". And yes, it is easier to write and read compared to other languages (old and new), but it does have some concepts that you should follow to write "idiomatic" Go code, e.g. don't throw panics as liberally as you would throw exceptions in other languages, use composition and interfaces where you would use inheritance in other languages etc. But I'm afraid people who have been indoctrinated with disregarding Go as "simple", but want to try it nevertheless (or are forced to use it), won't take the time to get into these details, and will see their preconceived opinions confirmed...
- dvfjsdhgfv 6y ago> Do people say that? I've never heard anyone claim that Go is simple to write. The article we are discussing now has a big subtitle "A simple language."
- hnlmorg 6y ago> Ignore comments about how go is simple to write. There's a fair amount of bad go code and people break rules all the time. This is one of the most famous straw man arguments made in software development and I've seen it used against a plethora of different programming languages -- each time completely missing the point that you can get bad developers writing bad code in any language. The fact it happens in Go isn't a testament not to how difficult it is but rather how good of a job the language has done attracting newer developers. > Go is not a simple language. Please learn from my mistakes, and ignore arbitrary metrics like how go has fewer keywords. The complexity doesn't go away, it's hidden away somewhere. I completely disagree. Having fewer keywords does make Go simpler to learn and simpler to read other peoples code. The opinionated nature of Go also makes it simpler to collaborate. Writing software isn't simple but that complexity of turning ideas into code doesn't change significantly from one language to another (generally speaking). You still have to solve a problem using logic and functions. I find the harder problems with software development is collaboration (eg ensuring everyone is following the same coding styles) and reading back old code. Go makes those things easier than some -- not all but definitely some -- languages. I say this based on 30 years of experience writing software in more than a dozen different programming languages.
- deleted 6y ago[deleted]
- doublerabbit 6y ago> Having fewer keywords does make Go simpler to learn and simpler to read other peoples code I partly disagree. It might be easier for you with 30 years of experience. Sysadmin with 8yrs of experience and having to manage operations utilizing Go is not easy. The code looks neat on the page; under the hood is really un-understandable at times unlike Perl, Ruby, TCL where the code is staring you in the face. The importation of modules off github is fundamentally wrong too.
- hnlmorg 6y ago> The code looks neat on the page under the hood is really non-understandable at times. Unlike Perl or TCL where the code is staring you in the face. Are you able to elaborate on this a little more? I love Perl and in fact that was my favourite language for a long time (despite all of its warts). But languages like Go are a lot more explicit that Perl so I'm not really sure what you mean by "under the hood" and "code is staring you in the face. > On vent: I also really loathe importing modules off github. I must admit that really annoyed me too but in fairness it's a pretty common pattern (eg brew, npm, etc). In a way Perl (CPAN) is an edge case rather than the norm. The difference is other systems add a shim around the code source even if they do still pull directly from (or from a cache populated directly from) Github et al
- adkadskhj 6y ago> OTOH, things like criticisms about it's error handling are overblown. At best it's a mild nuisance, and more often than not, a good thing that makes error handling explicit and clear. Yea, i'm a bit critic of Go (used it professionally for ~5 years, but no longer), but it's error handling is fine. Would i like Rust's `?` error handling syntax? Yes. Would i prefer better language tools for error handling (like enums/etc) rather than usually just wrapping strings? Absolutely. But the actual _need to error check_ itself is fine. I think it's funny, because to me the Go audience is one similar to NodeJS/JavaScript, aka one that favors features to improve prototyping. And while much of Go feels (at first glance) to promote this, the error handling does not. I prefer Go error handling. But i wonder if Try/Catch would have been more inline with much of Go's audience.
- Philip-J-Fry 6y agoIn my experience, Go is as simple as you make it and it is easy to learn. You can cover the whole language in a few hours. With anything that simplifies interacting with the underlying hardware there will be complexity hidden away from you. That's inevitable. Go is no different to any other language in that regard. The hardest part of Go is learning how to effectively use things like goroutines and channels. Slices might catch some noobs out, but at the end of the day it's as simple as saying "a slice is a view on a block of memory", so 2 slices can point at the same data, and changing data with 1 slice can be reflected in the other. Once you realise that a slice doesn't hold values there's no issues. That's simple, I just explained slices in 5 seconds. I think implicit interfaces are amazing. Yes it can be hard to figure out what implements it, but an IDE is used for that. Like you say, Goland is really good. Abuse of interface{} is bad, it's the worse decision that was ever made for the language in my opinion. But I don't think it's that big of a deal in the grand scheme of things. Generics will remove a lot of it's current uses anyway. I write microservices and the only time I have to touch interface{} is when using contexts. It's not for everyone, but people saying "Go isn't simple" are just as bad. You've got to understand people from all sorts of backgrounds have learned Go. For me, I really think it's easy to learn and simple to use. Others might think it's the hardest thing they've ever done.
- shp0ngle 6y agoAhhh Context. For me, using context and stuffing and retrieving things from it is the most painful part of go. If anything from go should die in a fire, it’s Context - well, the key value storage anyway. The canceling part is fine.
- Philip-J-Fry 6y agoContext is really good so long as what you're storing deserves to be there. For example, any UUIDs you generate for request tracing or anything like that. Once you start storing actual request data like users, or session data, etc. then it's a problem. I'm of the opinion that (if you're writing web services) anything related to the request should just be passed to the function using it. Shouldn't be stored on context and passed along 20 middleware handlers. If you need to share state this way then it's a failure of your design. Putting the meat of your business logic in multiple handlers is not the way. A handler is how you get the data into your application, then you can forget about them. But some people don't really understand that and start having authentication middleware, session middleware, user middleware etc. Just pointless complexity.
- kyrra 6y agoVSCode still works fine with Go, but I do agree that Goland is better. Gopls[0] (the Go language server) has definitely been getting better, but it was not-so-great for a while (it locks up from time-to-time and you have to restart it, but that may be better now). [0] https://github.com/golang/tools/blob/master/gopls/README.md https://github.com/golang/tools/blob/master/gopls/README.md
- bogomipz 6y agoI moved away from VSCode for Go simply because code completion was taking forever or sometimes failed to work at all. I believe that may hav e been related to gopls? Have others experienced this as well? Is that fixed now?
- RSHEPP 6y agoYeah I dealt with that for months, but it has greatly improved.
- kyrra 6y agoIn the command menu for VSCode (ctrl-shift-P on windows), there is an option called "Go: Restart Language Server", which tends to fix any problems with autocomplete or code navigation. I feel like I haven't had to use it as much recently.
- throwaway894345 6y ago> If anybody wants to learn go, ignore everything about how easy it is to learn. Because it's extremely deceptive. Take time to actually read through a lot of the important underlying concepts like how slices work. What is your standard for "simple" if learning how to use slices is complex? Go slices are just windows into contiguous blocks of memory. There are pitfalls--if you have two juxtaposed slices backed by the same contiguous block of memory, growing the former will write over the latter, but you quickly learn that you should virtually never be appending to slices that don't have sole ownership over their backing memory. Probably the worst part is that there aren't higher-level functions for prepending or deleting an item, so you have to build them yourself with append, copy, etc primitives (but even this has the nice property of exposing the cost of these operations, e.g., deleting from the middle of a slice is expensive and your average Pythonista probably doesn't understand this). > Ignore comments about how go is simple to write. There's a fair amount of bad go code and people break rules all the time. From official sdks to standard libs. Go can be extremely difficult to both write and read. This hasn't been my experience. > implicit interfaces I love structural sub typing ("implicit interfaces")--I can define an interface for a third party type which in a nominally subtyped language would require wrapping the third party type in a new type whose only purpose is to express the suitability of a particular interface. And for no real gain at all (or at least I've never felt myself wanting nominal subtyping; perhaps it's a difference in workflow). > judicious abuse of interface{} Putting aside the contradiction of "judicious abuse", I don't think `interface{}` is very common in Go, and where it exists it's usually appropriate, for example, JSON de/serialization or Printf. `interface{}` is used very sparingly in Go, and considering that people build real, successful applications in languages like Python and JavaScript where everything is an `interface{}`, Go's use isn't that bad. > Writing go can be difficult because of a lack of some language constructs that leave you unsure how to proceed. I particularly disagree here as well. There's often one way to do something in Go, and I've had very good luck by Googling "How to do x in Go?". > OTOH, things like criticisms about it's error handling are overblown. At best it's a mild nuisance, and more often than not, a good thing that makes error handling explicit and clear. Agree here. Maybe I'm an unusually fast typer, but the majority of criticisms seem to be about how long it takes people to type out the `if err != nil {` boilerplate. Personally my biggest criticism of Go is the lack of sum types (IMO I would much prefer sum types to generics). There are a lot of cases where it would be nice to express OR constraints. There are workarounds in Go--for example, using an interface with a private method that the variants must implement, but that's a lot of error-prone boilerplate and it tends to result in unnecessary allocations and dynamic dispatch (as opposed to a switch statement). Another criticism is that the compiler doesn't optimize as aggressively as I would like, including that many abstractions are runtime abstractions that could be compile-time abstractions (specifically, Go doesn't have semantics for distinguishing between a run- and compile-time abstractions and the compiler pretty much always assumes that all abstractions are runtime abstractions. > If you can, use goland. I use vscode and it's... not pretty. Almost every single thread I've seen on reddit recommends goland. My experience with vscode has been very unpleasant, particularly with go plus. I've been pretty happy with vim. I haven't used goland. vscode became noticeably worse around the time that modules landed, and IMO never fully recovered. `gopls` has also been disappointing. Go's editor story used to be best in class in general, but it seems to have gone downhill. Still, I think it's well above average (especially with respect to the dynamically typed languages).
- strken 6y agoWhen people say Go is a simple language, they mean that Go, the literal language, is simple. Some people are also claiming that the programs written in Go are simple, that the ecosystem is simple, or that using Go is easy, and those people are probably wrong. However, Go the language is actually simple. Here is the Go spec: https://golang.org/ref/spec https://golang.org/ref/spec. Firefox's print dialogue tells me it's 105 pages long. You can read the spec in an afternoon and digest most of it. Here is the ECMAScript 11.0 spec (known as JavaScript to its friends): https://262.ecma-international.org/11.0/ https://262.ecma-international.org/11.0/. Firefox's print dialogue tells me it's 1181 pages long. Here's the Java SE 16 spec: https://docs.oracle.com/javase/specs/jls/se16/jls16.pdf https://docs.oracle.com/javase/specs/jls/se16/jls16.pdf. It's 844 pages long. I can't post the C++20 spec because it's an ISO standard and it costs $399AUD for the privilege of reading it, but it's 1853 pages long in PDF form: https://www.iso.org/standard/79358.html https://www.iso.org/standard/79358.html. On a factual level, Go is a simple language, but so is the language Brainfuck, which has a sort-of-spec that's 9 pages long: https://github.com/brain-lang/brainfuck/blob/master/brainfuck.md https://github.com/brain-lang/brainfuck/blob/master/brainfuc.... Simplicity is not ease of use.
- nicoburns 6y ago> When people say Go is a simple language, they mean that Go, the literal language, is simple. Perhaps. But what use is a language that is simple if it doesn't make it simpler to use or easier to learn? I think most people who claim that Go is simple are claiming the latter, because the former is mostly uninteresting. It's good for IDE support I guess.
- strken 6y agoIt's a tradeoff. You get a simple language without a lot of surprising features, but sometimes code is very verbose; sometimes problems that would be trivial in other languages require unfortunate solutions like cgo, reflection, strange hacks[0], or code generation; and sometimes the "sensible" opinionated ecosystem doesn't fit how you want to work. [0] https://golang.org/pkg/sort/#example_ https://golang.org/pkg/sort/#example_
- 6y ago
- blacktriangle 6y agoSimple vs Easy rears its ugly head again.
- rufugee 6y agoI tend to agree with you and had a similar experience. I found a lot to love about Go, but also found things which were just hard to fathom or reason about. For example, ask a Go programmer, given an interface, how you are supposed to find all implementations of that interface. As of a few months ago, there just wasn't a good answer for this, although supposedly you could get there with gopls if you knew how.
- psanford 6y ago`M-x lsp-find-implementation`.
- david-cako 6y agoThe complexity is about the bare minimum to express concepts like concurrency, pointers, and interfaces, in my opinion. The ways Go seems complex are because it doesn't try to hide how memory works as much as other memory-managed languages, and in turn, as an engineer, you can write application and web-level code that performs almost as well as C and gets you thinking about things like a C programmer. I think Go just seems familiar to people that come from a variety of languages. For me, the simplicity, batteries-included, and minimal primitives are a breath of fresh air, whereas in many languages I've felt like I have to learn "a whole new thing" each time I plug in a new library or try a new framework. Go has a web server, JSON, SQL, crypto, compression, and more built in, and it's all stuff you'd want to use directly in production. In Go, code and docs are just easier to write and navigate too. Compare, for instance, the prevalence of Reader/Writer types to how all-over-the-place implementations of buffers and asynchronous code are in other languages and ecosystems, or how many different build systems, dialects, and frameworks most languages have. The locality of most Go packages means you'll find better docs and help, and more canonical examples of how to do something. Swift is another "deceptively simple" language to me. Swift has quite a few features, which means more prerequisite knowledge to read code "in the field". You're less likely to understand code by looking at it because there's more ways it can pan out while the developer is thinking about how to write it. I found that to be an especially big problem with JavaScript; I generally tell people to start writing JavaScript with a particular toolchain like React/TypeScript so they can set up a project and get on the right track fast. Go's ecosystem is opinionated but still just flexible enough, as I would say most of the features are.
- tene 6y agoThis really matches my experience, in that learning the Go language is very simple, but learning to correctly use the Go language to reliably build correct programs is much more difficult. The Go compiler (and other tooling like go vet and the race detector) gives me very little assistance or confidence in my work. The Go standard library is similarly very weak, leaving me to repeatedly re-implement things that are taken for granted in other languages, like common collection operations. One big example is Go slices, which are "easy to use" and "just do the right thing" up until they don't. If you append to a slice, it might or might not allocate a new backing array depending on the slice capacity, so whether your function is mutating an original or not can suddenly change based on changes in other parts of the code, and it's a huge pain to track down bugs like that. Go's channels are "Easy to get started with", but very difficult to correctly compose, or do anything nontrivial with. Reading from a closed channel will "successfully" generate zero values instead of failing to read a value. You have to replace your variables with a nil channel instead. When writing Go, I feel like programming by coincidence. With a lot of careful thought and work and testing, I can arrange for something that works, but it's fragile under refactoring and maintenance due to spooky action at a distance. None of the stdlib collections are threadsafe, but if you mistakenly share one between threads, it works fine up until you hit sufficient concurrency to have multiple concurrent mutations. Go is "easy" due to garbage collection, but that only handles memory, and offers you zero assistance in handling any other resources. There's no destructors, and no RAII, so you still have to carefully manually manage resource cleanup for files, database connections, locks, mutexes. Go's type system is too weak to express a mutex owning its guarded value, so it's left up to careful code review to ensure that the guarded value is only accessed while the mutex is locked. I feel like "the language" is simple, sure, but to successfully use it, you have to also learn many little constructs you have to repeatedly type out, and techniques to protect yourself from all the sharp edges. For me, the Go Language was faster to learn than the Rust Language, but learning to reliably build correct programs with Rust was way easier than learning to reliably build correct programs with Go. I like Rust because I am a mediocre programmer with poor working memory. Rust lets me build abstractions I can rely on, and reason locally in small parts while working on a program larger than I can easily fit into my head. Go makes some operations "easy", but unfortunately also makes shooting myself in the foot much easier than doing something safe and correct. The Go language itself is very simple because it abdicates all responsibility for correctness, leaving it entirely up to the programmer. You still need to handle all of the same responsibilities regarding ownership, resource lifetimes, locking, thread-safety, error-checking, exhaustiveness-checking, etc. but Go leaves all of that up to individuals to learn for themselves through trial-and-error, and ignores all advances in PL theory on how languages can assist with these problems. I could understand some of the appeal of Go if it was people saying they like to use it for half-assed one-off scripts that don't grow to large sizes and don't have any long-term maintenance, but instead I keep seeing people build large production systems with it.
- scottlawson 6y agoI think it would be a more productive discussion to ask whether go is a simpler language (compared to popular alternatives), not whether it is simple in an absolute sense. Given how complex computers and programming is, it's easy to argue that any language is not simple. It's a more interesting question to ask which of the languages is simplest.
- naikrovek 6y agoGo is simple in the very same way that Tetris is simple. It can be taught quickly, it is easy to make mistakes, and when manipulated by a skilled operator, is absolutely beautiful. Other languages are simple in the same way that landing a rover on Mars is simple: not simple at all. Every caveat I listed for Go and Tetris also applies to these other languages. So, all other things being equal, Go's simplicity wins, for me.