9 ms·
Why I Don't Like Golang (2016)
- Mathnerd314 4y ago2016. Generics have been added.
- deleted 4y ago[deleted]
- shantnutiwari 4y agoWhy does Go get so much hate here? Almost all front page articles are about how Go suCkS mAn I know Go isnt great or perfect, but still, why so much hate? I seriously want to know
- morelisp 4y agoFor many years Go has been displacing C/Python/PHP/Ruby/backend JS in situations where it's a clear win or at least the tradeoffs in tooling, speed, type systems, distribution etc. can be expressed in terms of agreed-upon technical priorities. Now there's a lot of Go code in the wild, projects people want to use or extend and programmers who will choose it by default, and it's starting to displace C#, Java, and C++ where the comparisons become a lot more preferential and vague. Do you want a faster GC or deterministic allocation? Nominal or structural interfaces? People fear change, especially in a field where change is only loosely correlated with improvement.
- mayormcheeseman 4y agoDo you think Go is really starting to displace C#, and Java though? I rule out C++ because I really think rust is the one aiming for that spot. But Go for C# and Java? Hard to say until we see Go start to take over more of the business domain applications within enterprise IMO.
- morelisp 4y agoI mean, for Kubernetes, Go literally displaced the prototype in Java. And the surrounding tools that are all now in Go, would likely have been in Java instead. You could say it's been successful in part because it's not Java and therefore Go "grew the market" instead of displacing anything, but I think that's pretty weak - some kind of DIY cluster management was coming, and the state of things is that Go snatched it from Java. I think Go is quietly taking over some business domain applications, reminiscent of Python ca. 2003 a lot of companies I see are using it for a few key components that benefit heavily from memory savings of value types and/or easier naive concurrency, but they're relatively quiet about it. There's also a small but significant cohort of junior devs today who learned to program by making games on fantasy consoles or homebrew hardware projects, want to keep working with those data-oriented patterns they learned C and C++, and Go supports that style a lot more idiomatically than Java. As much as I sometimes rant about "kids today", more of the current generation know the true value of a MB or a ms better than that of 10 years ago (Rust is helping a lot here, too).
- elpatoisthebest 4y agoTo be 100% fair, this post is a full 6 years old now. But also, I don't think it's specifically hate, it's more of a reaction to the overwhelming wave of posts here (and basically on every programming forum) from around 2014 to 2018. Go was so hyped it was unavoidable that if you were starting a project, dozens of comments would be shouting at you to use go. Some posts are people finally getting to say, "I told you so, but I was against the crowd a few years ago" Some posts are people saying, "Go doesn't really fit this use case" Some posts are people just academically sharing the language features you don't get when you choose go. Basically, in my opinion (and as a developer of a large go codebase that I really love), thousands of people hyped up go as a silver bullet or a "near-perfect" language. This is obviously not true, go has many downsides. When you tried to bring them up before, you were downvoted and pushed aside for the hype. Now that people are maintaining legacy go code, there's more appetite for these conversations about go's tradeoffs.
- mayormcheeseman 4y agoThere's definitely valid criticisms, but a lot of it seems like hate. But I also agree that it's probably a reaction to the earlier hype wave. I especially find it funny that people assume that people like Rob Pike and Ken Thompson who have published research papers on computer science forgot or misunderstand modern language features. They purposely made their language this way, for better or for worse. They never stated that they were trying to make the next Java. And all of the successful projects that have been released so far written in Go is proof enough that it seems they know what they're doing. People complain online for a language they won't use instead of using the languages that are "superior" to make useful modern software.
- deleted 4y ago[deleted]
- nemothekid 4y ago>There’s no ternary (?:) operator. Every C-like language has had this, and I miss it every day that I program in Go. The language is removing functional idioms right when everyone is agreeing that these are useful. And everyone agreed so hard that it was removed from almost every modern C replacement (Rust, Nim, Zig, Elixir, Kotlin).
- dragonwriter 4y agoRust has if/else (ternary) and match (N-ary) expressions, so it doesn't need a separate ternary operator. All of the other “C replacements” listed (which are a weird list for that description, especially Elixir, but whatever) have at least if/else-expressions, which, again, are ternaries.
- the_only_law 4y agoYeah if I can have decent pattern matching I can live without some other syntax sugars.
- ungamedplayer 4y agoHave you met my friend.. erlang ?
- the_only_law 4y agoIndeed, big fan, though it's rare I get to use it.
- V-2 4y agoTrue. In Kotlin you can go val foo = if (bar) "this" else "that" and you don't need two separate assignments.
- thegeekpirate 4y agoFor comparison, in Go it would be: foo := func() string { if bar { return "this" } return "that" }()
- implying 4y agoThey've fixed the import / modules situation to a point where it's usable and much improved, and generics have been added. However, the issue this brings up about structs / types not explicitly declaring which interfaces they implement is a real and unaddressed problem, especially in large codebases. The only tool that I'm aware of that finds implementations is GoLand, at steep JetBrains prices. Figuring out what type an API is asking for should not require reading every line of code in the package, and slows down every developer of large Go projects
- grey-area 4y agoThe interface defines the behaviour required at the point of use - that’s the point of them. You should not need to know which types implement an interface and if you do things are deeply broken in your codebase. I’ve developed large Go codebases and never had this problem so your last sentence is false. In addition this is not an issue other go developers I’ve spoken to have ever worried or talked about.
- voidfunc 4y agoWhen developers who usually make 6 figures of money complain about $90/yr IDE price I just cannot help laugh. Actually it's even better... the price elevators down from $90 -> year2 90 - 20% -> year3 90 - 40%. Over three years that's like $150-$200 total and it will save you so many headaches. But that's a steep price? Are you kidding? Why do developers hate tools that cost money when they save them time and allow them to do more?
- dehrmann 4y agoI'm shocked at how often I see software engineers not paying for Sublime Text. These are people who get paid to write software not paying for software.
- deltaonefour 4y agoThe use to pirate stuff all the time. Now it's actually more convenient for me to buy it. But the philosophy I always had was that as long as there were enough people like you paying for software, I wouldn't have to.
- jjtheblunt 4y agoTitle needs 2016
- deleted 4y ago[deleted]
- xigoi 4y ago> if I name my source file i_love_linux.go, it won’t get compiled on my Mac What the fuck?
- tandr 4y agoThere some file name conventions in place in Go [1]. Files ending in *_test.go are going to be run dufing `go test ` invocation, but not compiled during production build run. In general, last parts of file name reflect "tags", or a platform that this file should be built for. So, in the case of *_linux.go file will only be compiled when it targeted linux platform. Allows to have a file say file_windows_amd64.go and file_linux.go that have functions with same signature, but only one will be picked up for a target platform. Sort of like #ifdef , but at file-name level. There is a way to specify what file is actually targeting inside the file, through //go: "pragmas" too [1] https://stackoverflow.com/questions/25161774/what-are-conventions-for-filenames-in-go https://stackoverflow.com/questions/25161774/what-are-conven...
- tanduv 4y agoExplanation from a previous discussion - https://news.ycombinator.com/item?id=16414435 https://news.ycombinator.com/item?id=16414435 ...seriously wtf
- justanorherhack 4y agoIn 5 years of writing to code this has never prevented me from naming a file what I wanted to name it. I enforced conventions are nice, when I need to look at what’s different between platforms I can very quickly do so in any large repo.
- quickthrower2 4y agoSearching around a few blogs mention _linux.go files are only compiled on Linux. But I see nothing in the official documentation, will at least in my quick searches. It will catch someone out who uses BSD as an acronym for something in their domain model (Bulk Sales Discount?) then xyz_bsd.go doesn't compile.
- weatherlite 4y agoAs a new Go user I seriously don't get the hype. It feels like C with some (not many) niceties thrown on top, that's not what we expect from high level languages. I am still waiting for the tada moment, hope it comes.
- readlikeasloth 4y agoI don't want to spill the beans here, and well: you figured it already out by yourself.
- throwawaylala1 4y agoWhat are you using it for?
- weatherlite 4y agoCrud APIs...
- justanorherhack 4y agoIMO it’ll be slower to write crud apis and there are some missing batteries you have to look for, it’s fairly verbose but I think some of that will change with generics and hopefully more pattern matching. On the flip side when you deploy it, it will like just work and run smoothly. Also very easy to add full integration tests as you can create a mock http server at runtime, paired with some db tools (go migrate) it’s very easy spin up a whole env and test it. It’s also very easy to get at lower level things like headers and cookies without it getting in the way. Also much of the web middleware is interchangeable or a few lines away from an adapter as there is a common interface in the std lib.
- weatherlite 4y agoOK thanks for this, the easily mock thing is indeed very nice to have. And maybe Generics will improve things. I don't get why there isn't a function to remove element from a slice (there's some append[:i],[i+1] trick instead) why wouldn't this be wrapped in a stdlib function? call it delete or something. I keep hearing good things about the stdlib - what am I missing? It's that do it yourself mentality I really don't like, and taking huge compromises on readability to preserve low language keyword count (like the lack of private keyword / capitalization the article discussed and the consequences) and then calling this whole setup "simple". There's nothing major but many many small things I think that make it a subpar experience. I don't care that much about performance and concurrency though which I think are Go's strong suits.
- benhoyt 4y agoMy thoughts on his points, from someone who really likes Go and has used it heavily on small and large projects (1M LoC): 1. Probably a matter of taste, but I love this feature, just because of the lack of noisy public/private keywords everywhere that you see in Java et al. It also means you can tell from a usage (not just the definition) that something is exported, which is often useful. As far as renaming goes, either rename the definition and see where the compiler complains, or get your IDE to do it (I use GoLand, but good things are said about gopls). As for his example, the idiomatic way to write that is either just call it `usr` or `adminUser`, or use `user := &user{}` which is valid (if a little confusing). 2. This is a feature: it allows you to define interfaces only where you need them (on the consumer side), and you define the interface with only the methods you actually need. This means that when you add a bunch of new methods on the implementation, you don't need to change all the consumers. Go interfaces are amazing. The downside he discusses almost never happens: it's surprising, but even in large projects I've never had structs accidentally implementing interfaces or a IsAdmin method being implemented with reversed polarity by accident. 3. Definitely has its downsides. Tooling helps find unchecked errors. Though I've found the biggest downside to explicit errors is the verbosity. You do get used to it, and the explicitness is at least clear. 4. There are a couple of "magical" things like this, but they're well known and documented, and simple to fix if you run into them. I love the fact I can just name a file foo_test.go and add TestFoo methods, and "go test" finds them automatically. 5. I have not found this to be the case, and in the rare cases it does happen, the compiler tells you loudly and it's easy to fix. 6. Yeah, this is a slight pain, but the semi-official "imports" package (golang.org/x/tools/imports) fixes it up, so you just run generated code through that (and it auto-formats the code as well). It's a couple of lines of code. See: https://github.com/benhoyt/prig/blob/2df1b65a2bdf34c10bb5e57ecc99d1775bc9d196/prig.go#L134 https://github.com/benhoyt/prig/blob/2df1b65a2bdf34c10bb5e57... 7. Yeah, I wouldn't mind a ternary operator. Easily misused, which is why they didn't add it, but it would be really nice used judiciously, rather than the 4-line if-else block. 8. Fixed by sort.Slice, which avoids the need for Len and Swap (and even more so by the new generics "slices" package, coming soon). I guess this was added after the article was written? 9. Fixed by "Go modules", which is really well designed and works well (though opinions differ). 10. Fixed with generics being added in Go 1.18. And generic helpers like "slices" and "maps" packages coming soon. 11. Yeah, slightly annoying for newbies, though as he mentioned, tooling tells you. I do like the control you (can) get over allocation and memory management with Go slices. As far as his summary goes (eg: the type system getting in your way for large programs), I have definitely not found that to be the case. The author doesn't like Go, and that's okay! I don't like Java. :-)
- LVB 4y ago>The tried and true approach of providing a compare method works great and has none of these drawbacks. Agreed! https://pkg.go.dev/sort#Slice https://pkg.go.dev/sort#Slice is wonderful. (Added a bit after this article was written, I think.)
- srer 4y agoLets see what the Go doc example looks like: sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name }) In Python one might write: people.sort(key=lambda person: person.name) Or in Rust: people.sort_by_key(|person| person.name); // sort_by is also an option... I think it's worth calling out exactly what is happening in the Go example: - We create a closure that captures the people slice - We pass the people slice and the closure to the Slice function - The Slice function mutates the people slice, and because the closure captured the slice it sees these mutations too I get why the Go team wrote sort.Slice like that, and it was perhaps the best they could have done with the language features...But I think we're going to have to agree to disagree on how wonderful it is compared to other languages ;).
- throwaddzuzxd 4y agoIt's worth noting though that Go's way is just 40 characters more than Python with an inline comparison function and Go's verbosity. If I need to reverse the order, it looks easier to do with Go (just reverse the operator) than with Python and Rust way (I guess both have something like an "order" additional parameter). Rust and Python both feel more elegant but I actually like Go's way.
- abenga 4y agoPython has a `reverse=True` kwarg for doing this.
- IshKebab 4y agoGo's method is like that because it didn't have generics, but it does have the advantage of allowing you to sort more complicated things, e.g. indexes into other data structures, or computed values. Sorting by key is a special case (admittedly the most common special case).
- x3n0ph3n3 4y agoI'm still baffled by their decision around date formatting. https://www.godateformat.com/ https://www.godateformat.com/
- thegeekpirate 4y agoI wrote https://golangti.me https://golangti.me because I never remember _any_ of the formatting types (besides Excel (which isn't as extensive)—d, dd, ddd, dddd, m, mm, mmm, mmmm, mmmmm...).
- philliphaydon 4y agoThis makes no sense to me. First time I’ve been confused about date formatting.
- Beltalowda 4y agoI find 15:04:05 on Monday Jan 2nd 2006 a lot easier to remember than all those strftime %-verbs. I certainly don't see how "%B %e, %Y" is any better than "January _2, 2006". %B for what? Bonth name? And %e for "d for day plus one so %e".
- erik_seaberg 4y ago1999-12-31T23:59:60 would make it easier to remember what the constants are.
- Beltalowda 4y agoThe way I remember it is that it counts from 1 to 7: 2006-01-02T15:04:05Z-0700 It's unfortunate that the year is 2006 and sandwiched between the minute and TZ offset, but this keeps the day at Monday (1st day of the week, for many anyway) so that's nice.
- ngalaiko 4y agoanother person who can’t get over his java stockholm syndrome in three (!) years one particular thing that tells that is the attitude to interfaces: while in java (and most languages) interfaces are used to tell which contracts a class implements, in go it’s reversed. you must declare interfaces to _require_ certain contracts, for arguments in your functions for example: type interface Operator { Operate(int, int) int } func IntOparation(a, b int, op Operator) int { return op.Operate(a, b) } this is a major difference highlighting the ownership boundaries: * when I write a package and rely on a 3rd party contract, instead of referencing it and adhering to it, I will copy-paste parts that I need to my package and be independent
- deleted 4y ago[deleted]
- yashap 4y agoAgreed with the article, though obviously it’s a bit dated (especially around generics and package management). My take is that Go is basically the new Java, with fewer abstractions and faster compilation. Although, the pre-Java 8 Java, before Java started to get a bit functional. Like Java it’s a practical, imperative, statically typed, garbage collected language with very good performance. Also like (pre-Java 8) Java, it’s very verbose, doesn’t allow for much “elegance”, and many find it not very fun to write. But it is a pretty decent language for getting shit done. Overall, I don’t really enjoying writing Go, but it’s not the worst either. I’d code in it if necessary, but wouldn’t chose it for a personal project. I just have more fun and am more productive writing code in concise, mixed OOP/FP languages like TypeScript or Scala, even if they don’t compile as fast.
- digianarchist 4y agoSurprised you compare it to pre-Java 8 considering functions have first class support in go.
- yashap 4y agoFirst class functions are a lot less interesting without functional data structures, with methods like map, filter, reduce, etc. These were added in Java 8, but Go has always been against them. This may change with generics, people can certainly write their own now, but I’m on the fence about whether they’ll catch on. I think they still won’t be overly nice to use in Go because: - Go’s lambdas are extremely verbose. “Concise but clear” is a big part of what people live about functional data structures, Go won’t have the concise part - Go will still have almost no support for immutability, which works beautifully with functional data structures Code like this is nice to write: users.map((user) => user.id) While code like this isn’t: users.map(func (user User) string { return user.id })
- vippy 4y agoThe Scala ecosystem is super cool, once you're able to groc all of the neat stuff happening, sort the good tools from the bad, etc. Love http4s, scala-js, scalajs-react, doobie, cats, etc.
- deleted 4y ago[deleted]
- crowdyriver 4y ago> Go doesn’t have exceptions. It uses multiple return values to return errors. It’s far too easy to forget to check errors... Yes, because it is easy and predictable to track exceptions in nested try catches and hidden control flow.
- deleted 4y ago[deleted]
- pvg 4y agoPreviously: 2019, 296 comments - https://news.ycombinator.com/item?id=20166806 https://news.ycombinator.com/item?id=20166806 2018, 148 comments - https://news.ycombinator.com/item?id=16414098 https://news.ycombinator.com/item?id=16414098 2016, 47 comments - https://news.ycombinator.com/item?id=12356823 https://news.ycombinator.com/item?id=12356823
- thefaust 4y agoWhy isn't Go good for large projects? Kubernetes is an example of a huge project built in Go
- ihateolives 4y agoThis is stock example. Anything else?
- thegeekpirate 4y agoExcluding any lines that aren't Go code, and from projects that I can recall off the top of my head: Kubernetes = 3.87 million, Go = 1.75 million, CockroachDB = 1.65 million, TiDB = 725k, Consul = 375k, Nomad = 375k, InfluxDB = 375k, Mattermost = 370k, Vault = 345k, rkt = 320k, Terraform = 275k, Grafana = 265k, Ethereum = 245k, Gitea = 225k, Dgraph = 205k, MinIO = 200k, Rclone = 200k, etcd = 185k, Hugo = 120k, Prometheus = 120k, Syncthing = 110k, Traefik = 110k, Juju = 105k, Perkeep = 100k.
- ihateolives 4y agoOk, fair enough. Love Syncthing, didn't know it was written in Go. Though I wonder why they wrote MacOS client in Objective-C instead?
- gorgoiler 4y agoI’d like to get into go but in the past I’ve always been burned by not being able to quickly refactor my code. If I want to change the contract of get_kittens so that it returns a set instead of a list, I found it quite tiresome to then go to all the call sites of get_kittens and change their types to match. What was I doing wrong?* Perhaps there’s a cleverer tool out there that can infer and implement these type changes for me, automatically? * using vim? [joke]
- taki_mekhalfa 4y agoThis is true for all typed languages though..
- Zababa 4y agoNo, type inference avoids this issue.
- yencabulator 4y agoWhich Go has. https://go.dev/ref/spec#Type_inference https://go.dev/ref/spec#Type_inference (Not to a level something like Typescript has it, but I'll argue that's a win. Typescript inferred typing can be hard to follow.)
- kstenerud 4y agoAlthough go has many deficiencies, this is not one of them. When you use "var" or "val", it works like "auto" does in C++.
- sudo_chmod777 4y agoI also use Vim. 1. Use `:=` whenever you can, so types are inferred by the assignments/allocations 2. Alternatively query all references from `gopls` and put the results into quick fix list, then `:cdo`
- ridof 4y agoI just leave this here: https://github.com/golang/go/issues/49383 https://github.com/golang/go/issues/49383 After such public disregard to the communnity and contributors as a whole, the talk about good or bad has no meaning until they learn the basics. For example how to work with community, and the fact that you have to provide your phone number in order to fix urgent bug or implement some feature is a plain stupid(or rather malicious). Just imagine you've spent your free time working on the fix or feature, and instead of getting appreciation or sometimes bounty or just nothing, you're being "charged" to contribute. Yeah, they really think it's normal that contributors have to give up PI to the advertisement company that were accused of violating privacy many times before. They basically treat contributors, tech-savvy users who provide free labor, like their usual consumers. Just think about it for a second, this is insane.
- deleted 4y ago[deleted]