9 ms·
Ask HN: What do you like/dislike about Golang?
What I like:
- Ecosystem. Very easy to install and use libraries.
- Can compile programs to single executables easily.
- Easy to work with (Very productive) while also running fast.
What I disliked:
- The syntax but I'm starting to like it. (It seems that Go's syntax is an acquired taste for me)
- renaissance_tea 4y agoNot too many complaints. I like it much better than Java backend. Go and Typescript are now my go to for everything I think.
- ta3411 4y agocurious if you prefer Typescript or Go for backend development. My friend group told me they prefer Typescript because of shared code with client and ease of hiring.
- JoshGlazebrook 4y agoI have a nodejs+typescript backend stuck in a limbo state because of the whole esm modules fiasco. I have outdated npm modules I can't upgrade because they are ESM only, and I have old modules that will likely never update. It's to the point where I will only be using golang for backends moving forward.
- catlifeonmars 4y agoI’ve heard the shared code argument before, but in practice the only shared code I’ve really ever seen used is shared type definitions. Now shared type definitions are huge, but they’re a solved problem using JSON schema, GraphQL, or some other interface definition language that don’t necessarily require the same language in the front end and backend.
- cratermoon 4y agoThe quality of the standard library, especially net, time, and to a lesser extent, strings. The tooling, including the built-in testing package and test tool, and go doc. Also vet and fmt, if for no other reason than it precludes most arguments over braces and tabs vs spaces. I don't have cause to use it much, but pprof is a dream. I like the idea of the go module system, and the fact that dependency management is part of the language ecosystem. It's still a bit clunky, especially if you end up, like I did, stuck with a system that has lots of libraries with poorly-thought out dependency relationships. interfaces, especially single-method ones. But also the fact that your code doesn't have to declare it's implementing an interface, and has no dependencies on the interface declaration itself.
- ta3411 4y agoLove: - Ecosystem - Clean code - Single executable file Dislike: - Pointers -- maybe I am still getting the hang of it. But I feel like pointers throw off a lot of beginner programmers. Would love some practical advice here
- abdusco 4y ago> pointers Stick with pass-by-value and non-pointer receivers. Use pointers only if you have to.
- cratermoon 4y agoI worked with one team who deliberately chose pointer receivers for everything. Their reasoning? The compiler can't know if the receiver for the call you are making will be nil at run time, so it doesn't complain. Yes, they literally chose to subject themselves to runtime panics to silence the compiler.
- nebiros 4y agohere’s a good rationale about when to use pointers: https://stackoverflow.com/a/23551970/255463 https://stackoverflow.com/a/23551970/255463
- nikivi 4y agoDon't like error handling taking multiple lines (https://www.youtube.com/watch?v=raJGZaIPhOc https://www.youtube.com/watch?v=raJGZaIPhOc) Like everything else.
- bheadmaster 4y ago1. Static linking. I'm astonished by how many languages expect the end user to install dependencies/runtime themselves, and something about it feels very impure. 2. The "go" keyword (and the whole goroutine system underneath it). Threads are clunky, somewhat unportable and generally unscalable. Goroutines just feel right. 3. Ability to use multiple major versions of a library. Diamond dependencies are an unsolved problem in many languages I've worked with, but with Go you don't ever even think about them. 4. Implicit interfaces. Having to write "implements X" just to be able to use a type always felt wrong. Implicit interfaces just make sense. 5. The gopher mascot. I just love that little guy.
- jalino23 4y ago1. Static linking. I agree with this, coming from JS to learning C, and having difficult time compiling things. 3. Implicit interfaces. I'm in love with this idea when I learned of it. however it wasnt obvious that this should be a thing. if you learned interface from other languages first
- Winsaucerer 4y agoGood list. Regarding (4) Implicit interfaces -- to me, it's implicit interfaces that feel wrong :) Something having a method with a particular signature doesn't seem to me to be any kind of promise that it's intended to be used for the interface that expects that method. 'implements X', is a clear statement that yes, this method is made just for that specific interface. But this is just academic. I've never actually hit a situation yet where something just happens to implement an interface by chance, and does something completely unexpected.
- deleted 4y ago[deleted]
- liampulles 4y agoHere's what I do: ``` type Doer interface { Do() error } type CanDoer struct{} var _ Doer = &CanDoer{} // This ``` If CanDoer does not implement Doer, it will fail to compile, and you can quickly see what you need to do to fix.
- fwsgonzo 4y agoFor me Go is unique in that it can produce a fully static binary that can fetch from a HTTPS endpoint. It also supports many architectures. On top of that the package system and it's just way more convenient to use than other languages. Easy to learn, easy to put somewhere in practice. Not every program has to be 100% safe and delivering 2M req/s. Sometimes you just want to build a program once and ship it. What other language has that? Go isn't perfect though. It's startup sequence is long, the API towards C (and other languages) is quite bad, and if you build a fibonacci program and compare it with C it's 3x slower despite requiring no allocations whatsoever.
- pjmlp 4y agoStatic linking predates dynamic linking by several decades, hardly unique.
- joshuak 4y agoWait, what prior programming language is compiled, can be statically linked, and has an https implementation in it's standard library?
- jolmg 4y agofwsgonzo never said anything about it being in the standard library.
- joshuak 4y agoWell that's not on him man. You are the one calling him out for being unaware of static linking, when you don't even seem to understand the full set of pros he listed in his first sentience.
- jolmg 4y agoYou're not replying to the same person. In a separate comment, I asked for a clarification on that specific part of their comment. The other pros, they're not part of what I asked about. In the comment I replied to you, I'm just stating that you're bringing up something that's not in discussion.
- bpicolo 4y agoThe answer to both is "it's boring".
- alecthomas 4y agoSo true :D
- indymike 4y agoWhat I like: - Easy to deploy - Short learning curve - goroutines What I don't like: - c bindings are not the best - Error handling code gets old, but at least it's always consistent and never magical
- SchmoLang 4y ago
- yzsh 4y agoLike: 1. Expansive Stdlib: it’s great to know there’s a working library I can rely on that will have long term investment for most things 2. Compile times are fast 3. Readable libraries. It’s pretty easy to folllow go library code Dislike: 1. Interface{} and gotos. They are easily avoidable in production code, but they open up some weaknesses in working with third parties. 2. Error handling. It should be a compile error not to handle a Retuned error without an _.
- yjftsjthsd-h 4y agoIt's a very practical language, and I like its affinity for static binaries. A downside is Google's approach to handling modules: https://drewdevault.com/2021/08/06/goproxy-breaks-go.html https://drewdevault.com/2021/08/06/goproxy-breaks-go.html
- morelisp 4y agoThis seems to only be a complaint about a particular (granted, default) proxy for downloading modules, and no criticism of the actual module system (which does not depend on a proxy) nor the idea of a proxy (which is pretty easy to run, especially when compared to most other languages' package repositories). As to the criticism, if a public module isn't playing well with the default proxy, it's a good sign I don't want to use it to begin with.
- yjftsjthsd-h 4y ago> about a particular (granted, default) proxy Yeah, but defaults matter. That's one of Go's big selling points, usually. > As to the criticism, if a public module isn't playing well with the default proxy, it's a good sign I don't want to use it to begin with. The concern raised here is more that things only work because the proxy masks problems. Also alluded to is that said default proxy is kind of awful to its upstreams, unnecessarily pulling things and burning bandwidth.
- morelisp 4y ago> The concern raised here is more that things only work because the proxy masks problems. But making the modules available in the face of upstream breakage is a point of the proxy. I can still build when GitHub is down. I can still get the version of the source I expected when upstream rebases or retags. Those are reasonable defaults. And with one env var I can also turn that off and check that the upstream is still as I expect. > Also alluded to is that said default proxy is kind of awful to its upstreams This is debatable; sr.ht seems to want to host a lot of go repos but not have people pull a lot of go repos. I'm not sure that's a case worth catering too.
- hinoki 4y agoAs someone who likes async/await/coroutines, I really miss them in Go. Channels are the GOTO of synchronisation, they lead to confusing spaghetti code because there is no structure. Go is really nice to read (once you get used to the fact that half the lines of code in any function are for error handling) unless it uses a lot of channels. Then you need to take great care to understand every <-.
- dom96 4y ago> As someone who likes async/await/coroutines, I really miss them in Go Interesting. Most complain about languages with async/await and say they want goroutines. What is it about async/await that you prefer over Go's approach?
- zinodaur 4y agoNot OP, but I am also in the camp of "like goroutines, not a fan of channels". Low cost threads are great - but channels can represent so many intermediate states, especially when error handling is involved. I wish there was a simpler default for coordinating goroutines (Do we add an error field to the struct we send through a channel? Do we close the channel on error, or only on success? Do we make a separate channel to send errors on - and if we close that one it means for sure that there were no errors? If we select on the two dependent channels, do we have to make sure that they are in different sequential selects, so that we don't go out-of-order or deadlock?)
- hinoki 4y agoAsync/await allows you to be much more explicit about dependencies. I don’t care what thread executes something, but I do care that e.g. these three network requests happen in parallel. With async/await I can explicitly use an ‘await Promise.all(a, b, c)’ where Go would need a new channel and goroutines, etc. all being implicit, so it’s hard for the reader to know what the intent is, and it’s error prone, who knows if you properly clean everything up.
- morelisp 4y ago
- ubaltaci 4y agoLike: get things done mentality, green threads, duck typing, default formatter. Dislike: still no easy way to dynamically create mocks -maybe some brave soul will try to solve it after generics :)- I don't like code generation or manual mocking, we have a large codebase, 1000+ file and so much noise in the repo because of generated mocks. And yes we are fan of unit tests and aiming 100% coverage on business logic.
- pjmlp 4y agoWhat I like, It is a nice language had it been released in the mid-90's, following the footsteps of Oberon and Limbo. What I dislike, Being designed a decade later ignoring everything that happened in mainstream computing since Oberon and Limbo came to be, then adopting features that weren't properly backed in from the get go.
- tech_tuna 4y agoCan you elaborate more on what was ignored? For one, I think it's mind blowing that they didn't have a good system for dependency management in place from the get-go. Things are pretty good now with go modules but it's like they never even heard of languages like Python and the unholy mess that package management was (and still is to some extent) with Python.
- majewsky 4y agoNot mind-blowing at all. It's originally a language designed by Google, for Google, and Google famously uses a monorepo for most of their code. If you have a monorepo, package management is a non-issue.
- pjmlp 4y agoThe whole generics drama. The const/type declaration dance to this day, to declare enumerations, even Algol could do better. Error handling based on comparing strings, to find out the real cause.
- apgwoz 4y ago> Error handling based on comparing strings, to find out the real cause. I'm not a fan of Go, at all, but credit where due: they did make this slightly better with error wrapping (https://pkg.go.dev/errors#Is https://pkg.go.dev/errors#Is). Of course, this doesn't work unless errors are wrapped, instead of blindly concatenated, forcing you to do string matching more often than not. :)
- mkl95 4y agoLike: standard library and readability. The "If it ain't broke, don't fix it" philosophy that I miss from the earlier Python days. Dislike: awkward error handling and testing / mocking
- closeparen 4y agoPro: - Community. Pragmatic, high signal to noise ratio in online resources, little magic, sympathetic to the needs of production operations. Consider for example httptrace [0]. This kind of introspection isn't even normally possible in many languages and their library ecosystems. In Go world, people care about this stuff. - Standard library. High quality and flexible packages for stuff like web servers and clients, TLS certificate manipulation, SQL, various data encodings, etc. - AST package, strong first-party support for manipulating Go source files. - Table driven testing norm is very cool in certain circumstances. Con: - Verbosity. Something like making an HTTP request is ~7 different operations, each with their own error branches. - The tedium of meeting coverage mandates. Having to code-generate tons of mocks and type out very elaborate test tables for what feels more like busywork than genuine confidence-building. Partly this is my employer's fault for having high coverage standards though. - Despite its apparent simplicity, there are significant footguns lying around slices, loop variable captures, channel deadlocks, etc. - The Go community's solution to a lot of language shortcomings (verbosity, type system, etc) is code generation. For example, we have an internal framework for parallel task graph execution, which is much safer and cleaner than manually managing channels and goroutines. But this kind of thing cannot be expressed as a regular library like it would be in other languages. - Despite the prevalance of code generation, Go does not quite have a macro system, leading to third-party build systems like Bazel in companies that do a lot of code generation with their Go. This then leads to rough edges with the other tools' handling of "de-materialized" generated code and the need for stuff like GOPACKAGESDRIVER for proper editor support. Editor and debugger support for generated code, the way things stand, can be rough. - Certain syntax rules such as trailing commas and unused variables/imports (especially when commenting stuff out temporarily to debug something!) can get on my nerves. [0] https://pkg.go.dev/net/http/httptrace@go1.19.3 https://pkg.go.dev/net/http/httptrace@go1.19.3
- oracardo 4y agoBelow are my current feelings having worked with it as my primary language over the last 16 months. My previous 7 years of development focused on Java, C++, Python, and JavaScript. Like: - Standard Tooling: formatting coverage, dependencies, BIN install, versioning, vendoring all done in Go CLI - Opinionated, minimal design: often I feel like there are fewer ways to do things in Go than in other languages. - Readability: fewer operators and minimal language design make it feel easier to ramp up and read most go programs Dislike: - Hard to master: some elements are very unintuitive coming from other languages (interfaces). I feel like a lot of content on go.dev is out of date (Effective Go). The Google Style guide is helping to light a path and when they publish Go Tips I think it will get better. - Too Minimal: in some cases it feels like Go went too far in not building language features (no set, use map[$TYPE]bool instead or map[$TYPE]struct{} for more efficiency but less readable imo)
- peterashford 4y agoLack of a set type is just bizarre to me
- nulld3v 4y agoLike: - Ecosystem - Static linking - goroutines - small and light runtime - fast compilation speed Dislike: - missing shorthand lambda functions, making functional programming very painful - typed nils - billion dollar mistake (lack of non-nullable types) - implicit/automatic copying on value types. Value types as a whole need to be re-thought. - too much error handling boilerplate - unused variables are compiler errors - struct init not exhaustive
- erik_seaberg 4y agoI forgot about starting with nil and ending up with an interface where every method will immediately panic, yet doesn’t equal nil because it’s carrying a type around. Reminds me of the HHGG box containing “no tea: just like the tea professional hitchhikers don’t carry!”
- DominoTree 4y agoHaving to use reflection and the interface{} (now 'any') escape hatch to see what fields are in an unknown JSON object "the pragmatic way"
- binarynate 4y agoLike: - Compiles to a static binary that's relatively small compared to something like .NET AOT. - Structural typing. - No semicolons. Dislike: - Lack of exceptions. I can understand wanting to avoid exceptions for safety critical software like avionics, but for most application programming, requiring manual error handling for every function call is cumbersome and unnecessary. - Too verbose / lacking features. For example, there's not a short syntax for lambda expressions, like the => operator in C# or JavaScript. - Public / private access modifiers at the package level rather than the class level (there are no classes). - Language development is driven primarily by Google, who has a history of killing products.
- brian_rak 4y agoLike: The package and build system is amazing and just works. Simple, yet intuitive and powerful with the introduction of modules. It's hard to quantify the number of hours I've saved over other tools hunting down build/linker/dependency management issues. Dislike: Error handling feels extremely verbose. I like the design choice to return errors explicitly, but it feels like there needs to be a return-if-error syntactic sugar introduced to avoid the endless if err != nil ... return err peppered everywhere.
- closeparen 4y agoHaving worked with Go from the days of vendoring, to Glide, to Dep, it is really amazing to see Go turn its greatest weakness into one of its greatest strengths and most-loved features. It was worth the wait. Here’s hoping the rest of my gripes follow a similar arc.
- ooninoob 4y ago> Like: The package and build system is amazing and just works. I don't have much experience with go, but that's not at all my experience. I had the compiler panic on me for daring to run "go get", as described here: https://github.com/golang/go/issues/47979 https://github.com/golang/go/issues/47979 This issue has now been closed, but there are several others open with the same symptoms. The response by a golang maintainer was: > It seems likely that there is still a bug here, but the code is complex enough that we're unlikely to find it by just reading through the code. Anecdotally, i've tried to fork the imported module to remove some dependencies i was not using, and failed miserably, as explained here: https://github.com/ooni/probe-cli/pull/986#issuecomment-1327446013 https://github.com/ooni/probe-cli/pull/986#issuecomment-1327... I have experience with C/Rust import systems and i can say with 100% confidence that golang's module system is far from amazing.
- ohCh6zos 4y agoLike: -The go AST package was a pleasure to use Dislike: - Boilerplate error handling - Excessive verbosity - Multiple return not being of a type - Duck Typed interfaces and the empty interface - Go generate that makes verbosity worse - Case-sensitive namespacing that leads to hunts for all the instances - Namespacing in modules that leads very large files - Shadowing rules that let you shoot yourself in the - Rules around =, := and var - Slice tricks and for loops try to encompass iteration instead of something like list comprehensions - Nullability and default values - Short variable names to the point of being meaningless even in the standard library - The go community's seeming insistence on a singular or idiomatic way to do things - The standard library is missing basics Edit: Added some formatting.
- nitwit005 4y agoThe simplicity is nice. It's one of the more readable languages. I particularly like that reflection has sensible limitations, so you can't produce the ridiculous frameworks that appear in Java and friends. I wish channels and goroutines were more strict, so that you could have some basic assurance no race conditions can be present. Defer is very convenient, which is a problem, as it is a source of bugs. It's usually used to ensure file-like objects get closed, but generally those return important errors when closed. A simple "defer file.Close()" will silently ignore the errors generated.
- ufmace 4y agoLikes: - Big standard lib, including SQL base classes, allowing very consistent DB code. No 6 different ORMs and slightly different DB code for every DB type. Ahem Rust. - Cross-compiling is easy and consistent Dislikes: - Error handling. Done to death, but it direly needs some syntax sugar like Rust's `?` operator. Seems like 3/4 of any function that does anything significant is `if err` branches. - Nullabilty and the way references work feels like a footgun. Rust feels more clear about what's happening when. Not sure there's much to be done about it now though.
- liampulles 4y agoLanguages must choose tradeoffs, and I think Go gears its tradeoffs towards large projects. Generally the larger a project becomes, the longer it takes to add features and fix bugs - so to combat this Go favors quick compile times, easy monorepos, simple tooling, and most of all: very consistent code. Go's limited syntax is a feature, not a bug. Syntax sugar in a language allows for writing code quickly, but it (arguably) opens up more opportunities for bad code - e.g. using language features inappropriately, mixing the "sugar" approach with the "manual" approach in the same codebase, being terse and hard to read, etc. If most of a developer's interaction with code is spent reading rather than writing, then it makes sense to value quick to read but long to write code. Go's philosophy of there being "one way" to do things (arguably) achieves that. Having a very transparent control flow (including treating errors as simply values) is in line with that. Yes errors pollute one's code - I would like an operator for that, but I'm glad the error conditions are being represented clearly. Go is perhaps not a good language if you want to get an MVP going quickly, or write something with a performance focus. Disclaimer: I love Go. I taught myself Go while I was working as a Java dev and it was a big factor in me finding a new job.
- bit-101 4y agoLIke: - Decent speed of compiling and execution. - Expressiveness. - I like the struct/receiver/interface interplay to create an analog of classes. - Nice standard library. - Cross compilation. Things I wish for: - Ternary operator. - Something a bit closer to inheritance. Embedding structs in other structs fools you into thinking there's inheritance, but you quickly learn that it doesn't work the way you think it will. - At the same time, fully implementing a functional programming paradigm isn't particularly easy either. But all in all, I'm a big fan.
- jstx1 4y ago> LIke: - Expressiveness. Isn't Go deliberately not very expressive?
- zerr 4y agoI dislike job descriptions. For some reason, most Golang positions are actually DevOps positions (Kubernetes, AWS, etc...).
- marvinblum 4y agoWithout adding another comment about syntax or language specifics, I just like that you can get shit done and stay sane. I have fewer bugs in Go because it's easy to read and because adding unit tests is easy. Deployment is simple because it compiles to a single binary. I don't need to mess with libraries too much because the standard library is almost all I could have asked for. I can show code to other devs, and they understand it even if they don't know the language. What I don't like is that Rust is also very intriguing to me :D
- Winsaucerer 4y agoLike: - Concurrency. Can shoot yourself in the foot still, but it's overall pretty simple to get started and use. - Small language surface. Fairly easy to keep most or all of it in your head. - Good ecosystem, and easy to pull in libraries. - Good standard library that does a lot out of the box. - Easy for new people to get started with it. - Compiles to a single static binary. Dislike: - Cluttering of my code with boilerplate error returns (a common criticism!). - Can't stop consumers of a library from doing the wrong thing. E.g., ensuring that someone always initialises an internal map of a new struct instances is challenging, with tradeoffs for each option. - In line with previous, overall lacking the language tools to enforce correct usage or behaviour. - Lots of footguns.
- dijit 4y agoI'm a sysadmin type, so take this with a grain of salt. Like: - Compiled and can be run as a scripting language. - Easy to learn, quite simple to use (even concurrency!) - Cross compilation is an environment variable setting. - Fast compilation, though apparently this gets worse with reflection and generics (and it's not that important to me honestly) Dislike: - The opinionated build/dependency system, which sort of doesn't work with monorepos unless you do things that "are not recommended" like `insteadOf` - When deserialising things (JSON for example), an omitted key becomes an empty value. As many will tell you, there is a difference between 0 and Null/None. - Case based visibility. That feels like the opposite of clear. - Slice semantics, easy to accidentally override values if you're not careful. (slices are references to arrays, you can reference a subset of a slice which looks like a new slice, but appending to it will overwrite a value in original array, because when you do `var slice_new := slice_old[0:30]`; it's really just a reference to slice_old, not a new slice with the contents from 0-30.
- liampulles 4y agonit: One can use pointer values for marking JSON fields as optional, and thus distinguish between the 0 and nil case. I felt similar to you initially about the difference between 0 and Null/None - I have to say that once I started modelling my APIs so that these two cases could be treated equivalently, I think the quality of my APIs improved.
- michele 4y agoNot really: it still can't tell the difference between a null value and a missing field which is different when working with APIs as a missing field usually means "don't touch it" while null means "nullify it"
- cratermoon 4y agoI love case-based visibility. I don't have to look at any declaration beyond the name to know if I can use the identifier outside of the package it's declared in. In most other languages case is just convention and visibility is determined by another keyword. Yes, I know programmers who came from a Java or C# background who continue to use naming conventions from those languages, to their detriment. I don't blame Go for their problems, though.
- erik_seaberg 4y agoAt 2/3 of every screen, error handling is absurdly noisy. A DSL for wrapping and bubbling up errors (the 99% case) is desperately needed. The builtin containers just suck. They’re always mutable. Map write conflicts might panic, yet there’s no support for preventing them. They aren’t comparable, which can cause panics elsewhere. You have to pretend slices have move semantics, because copies may or may not share state after an append. They don’t implement any interfaces, so you can’t even replace them or reuse their sugar. Functions can return tuples, but tuples aren’t first-class, there are no maps or channels of tuples. No overloading, each type sig needs its own func name and IDE refactoring won’t choose the right one. Reflection is very limited. No access to types or functions by name. No type or func or arg annotations, just a single string on a struct field. The GC design is pretty old and people go out of their way to avoid relying on its throughput. Liked: The memory footprint is pretty small. Parts of the community are starting to rely on code generation to work around the base language (e.g., piles of ignored boilerplate because Mockito can’t be implemented at runtime).
- sidlls 4y agoLikes: - The build/test tool is pretty good - Opinionated formatting/style is nice (even if I disagree with some choices, it removes a huge organizational bikeshedding problem) - Explicit error handling Dislikes: - The generics implementation leaves a lot to be desired - Structural typing: may as well be a dynamically typed language (I know it’s not that bad, but sometimes it feels like it) - The terrible implementation of nested/embedded errors and lack of support for structured, pattern match inspection of error return values tend to make error handling unnecessarily verbose - The insane use of interfaces literally everywhere, and the tendency for hidden/unexpected use of “reflect” leading to funky performance issues
- tialaramex 4y agoGo lacks things I decided I must have, including Sum types and a string type which doesn't just think "string" is a fancy word for "Some bytes". So I no longer use it in anger. As a result these judgements are perhaps a year or two out of date: I don't like the error handling, and I don't like that they basically punted the hard problem when it comes to data races. I do like the broad range of stuff in the standard library, and I like how slim its garbage collector and runtime in general feel under use. Start-up time in particular is pretty good for a language with garbage collection.
- AntiMS 4y agoLike: - `go generate` for embedding resources into the executable. So intuitive and beautiful. - Strict curating. It's the kind of language that things don't get into unless they're the right solution. - Performance! Python was my favorite language before Go got sufficiently mature. It was refreshing to have that much efficiency coming from Python. - `if err != nil {`, dammit! - Imports referring to the location where the code can be got. `import "github.com/fogleman/gg"` for instance. - `go fmt`. Nuff said. - Tabs as the standard indentation character. - `fallthrough` - `init()` Dislike: - nil. I wish nil had a smller role in the language. It's an agreed best practice in Go that a zero value should be a ready to use thing. I feel like that would be easier to do (and more true of the core language) if the zero value of a slice/map was an empty slice/map, the zero value of a pointer was a pointer to a zero value of the type it points to, etc. Maybe this can't be done for all types (function and interface types, for instance), and maybe there are good reasons for the way it is that I'm not smart enough to realize, but if it could be done for some types, it would be nice. Things I Pretty Much Eschew: - Generics are limited. Maybe I'm missing something, but I doubt I'll be using generics as they are very extensively at all. If we could make generic types that would be something I could see myself using more. - Embedding. It's rare I find a use for that. - `defer`, honestly.
- morelisp 4y ago> If we could make generic types What do you mean by this? Methods?
- sidlls 4y agoGenerics as currently implemented in go are so limited that you may as well stick with interfaces for anything but trivial boilerplate or textbook data structure/algorithm implementations. For example, it's currently impossible to define type constraints with user-defined interfaces embedded: ``` // this is legal type MyConstraint interface { int64 | float } type SomeAPI interface { AMethod() error } // Nope type CantHaveThisConstraint interface { int64 | float | SomeAPI } // NOPE func SomeGeneric[T CantHaveThisConstraint](...) { } ```
- spiffytech 4y agoMy big complaint with Golang is the way they (don't) handle nulls. Golang treats null as a memory initialization problem, while ignoring its semantic use. You still encounter nulls when interacting with external systems, and Golang has inconsistent ways of handling them. From memory (it's been a while): - Nullable DB columns return a struct with the value, and a boolean for whether the value is actually the value, or a placeholder for null - Requesting a non-existent query parameter from an inbound HTTP request returns an empty string. That's "fun" to debug. - Decoding a JSON object with a null value omits the key+value completely. There's no way to tell the key was ever present. This is a problem when you don't control the originator of the JSON. - I think maybe sometimes null pointers are used?
- peterashford 4y agoI think it's a very pragmatic language and I like that. I hate the error handling. I dislike implicit interfaces - they make refactoring harder. The existence of interface assertions is an anti pattern. The standard library leaves a lot to be desired. It's very much not a "batteries included" language. The go community are super defensive and resistent to criticism. So many times I see people ask reasonable questions about something lacking g in go only to be told that it's their fault for wanting it. I may sound negative but I actually rather like go. But no language is perfect, obvs.
- cesarb 4y agoIt's been a long time since I last looked at golang, but the first time I met it, I instantly disliked the way it imposed its own idea of filesystem organization onto the user. I wanted to run a Heartbleed checker, and instead of being able to clone the repository into a new subdirectory inside my ~/projects and compiling and running from there, like I would do for projects written in any other language, the go compiler required that the project was cloned into a global centralized path, where all projects written in golang would end up, mixed together without any separation.
- majewsky 4y agoThe requirement to work in GOPATH has been dropped around 2018. Nowadays, by default Go is running in module mode which works pretty much like in all other languages with builtin module management.
- didip 4y agoGo is the best. Go’s culture of minimalism, pragmatism, and just get things done is also amazing. What could be better: - Even faster runtime. - Even more efficient garbage collector. - Sum types would have been nice to have. - Structured logging would be great to have. - Structured error would be nice as well. - Cgo could be better. - Memory arena would be great for database applications. - Buffered channel is not as useful as I thought. - Better channel performance would be nice. - Closing a channel is not safe and easy to make a mistake doing it. - Embedding could be improved. - Standard library needs a lot more data structures. - It needs a tuple data structure so that users can return (result, result2, error). If this exists, we can create a nice chainable libraries. - gopls automatically generating test struct as a second implementation of an interface would be super nice to have.
- michele 4y agoLike: - Simple concise syntax - Great std lib - Most of the times it's easy to do the right thing Dislike: - No concept of NULL values and what it means especially when dealing with JSON - Limited handling of TCP connections life-cycle I'll add something which is not a language issue per se but I had to deal with a lot: often new devs to Go will try to force certain mental models acquired with other languages/frameworks onto Go and that makes for some terrible Go code.
- ooninoob 4y agoI'm new to golang, but i've had bad experiences with it so far compared to other languages. - method declarations are hard to grep for because the related struct appears before the method name (like "grep 'func String'" will not find "func (s Struct) String"), and because a module's types/functions can be declared across several files - many pointer-related footguns, many others have mentioned the nil pointer exception issue, but as a newcomer to golang i found it confusing that i could accept value params in methods/functions and mutate those params... only to have those mutations silently discarded because they were a copy of the original data to start with - do you even concurrency?! i ran into a deadlock by using the stdlib in a very simple way, in a sequential manner, in a single-threaded program. i still have no clue why that is, and the program maintainers don't either. i'm probably doing it all wrong, but it was so easy to shoot myself in the foot. If someone more experienced wants to teach me what i did wrong, here's the code: https://github.com/ooni/probe-cli/pull/989#discussion_r1032585034 https://github.com/ooni/probe-cli/pull/989#discussion_r10325... - the module system is entirely broken: i've had the go command panic* on me for simply using "go get"... the problem is old and well-known, and has quite a few tickets open on the golang bug tracker: https://github.com/golang/go/issues/47979 https://github.com/golang/go/issues/47979 - the attributes exposed by marshaling libraries are different from one library to the next... i mean that's a problem in most languages but after trying out serde.rs briefly i feel like that should be the way in every language to just standardize those fields - golang is not structured for commenting out parts of the code to test something quickly: unused imports/variables is a compilation error, and apart from naming a variable "_" there is no way to ignore its usage (using "_" as a prefix like in rust would be an awesome addition) - struct declaration and instantiation has inconsistent syntax: why would i use comma after a field instantiation but not after a field declaration? - the difference between ":=" and "=" is clunky... as you refactor code you end up having a lot of this variable doesn't exist, or this variable already exists kind of error... i understand the need for proper variable instantiation and type declaration in general, however ":=" does neither as you require an entirely different syntax (var) for explicit types, and golang is very happy with passing around nil/empty values - publicity based on case makes it super hard to decide later whether you want a method/field to be public because you need to change the entire API, instead of simply adding a keyword - no standard way to define default fields for a struct? there may be one but across all libraries i've used so far there was weird NewStruct() or NewDefaultConfigStruct() methods which were hard to grep for in the docs/code All in all, it's not the worst programming language i've used. JavaScript is a lot worse. But from a week of working with it full-time, i feel like go has massively failed at being a better C or a better Python... it feels to me like it combined the failure modes from both ecosystems into a new rather incoherent language. If you're looking for quick scripting, i would still recommend Python or PHP which in my humble opinion have much better developer UX. If you're looking for serious systems programming, i would recommend Ocaml, Rust, or plain old C, all three of which have amazing tooling. It may be weird to recommend C as an alternative to golang, because C is so low-level it's easy to shoot yourself in the foot... but that's the thing, C does not try to pretend to be a safer high-level language, it gives you raw tooling. golang tries to be higher-level but i think it failed at that. Sorry for the rant, i don't mean to be rude. I just don't understand the hype around golang.
- lormayna 4y agoI migrated my scrapers from Python + BeautifulSoup to Go + Colly and it was a pleasure: the new programs are impressive fast (1/3 of the time) and managing the concurrency and parallelism is a lot easier in Go that messing up with asyncio. Even the dependency management is a pleasure, no need for virtualenv or other tools. If there is something that I don't like it's the serialize/deserialize of JSON objects: you need to know the structure of JSON in advance and define in your struct. When you are scraping an unofficial API and this change silently, this can be a pain.
- thiht 4y agoLike: Errors as values. Would I prefer Results/Options baked into the language? Yes. Am I glad we don’t have to deal with exceptions? God yes. Stdlib, the ecosystem, and globally the mentality of the community regarding dependencies. Mostly self contained binary that’s easy to (cross) compile and deploy Performance Dislike: Lack of ternary expressions Lack of some standard interfaces (Iterable is a big one)
- musha68k 4y agoAside: has anyone read “100 Go Mistakes and How To Avoid Them” [1] and would care to share their takeaways? After getting back to it after quite some years I’m still conflicted about the language and its tooling. It’s a frustratingly (and seemingly) primitive/simple language but also a very productive one. I personally don’t love golang but it’s a great tool “for the common programmer / worker”. The unix philosophy is baked in without the excitement (to me). That’s OK. Also the stdlib has similarly great / lacking characteristics. It’s strong but then often missing basic functionality that you just don’t want to maintain yourself any more (e.g. try to do a unix like sort / unique on a slice of strings - afaik only lexicographical sorting in there). I would say that the main driver for my rekindled interest in the language stems from its current Lingua-Franca aspects for “higher level systems programming”. I’m thinking Kubernetes and Terraform here for example. In many ways but especially in this one it’s similar to Python actually - which I also don’t love at all - but which FWIW found its niche as the current go-to scientific computing and machine learning language / ecosystem. [1] https://www.manning.com/books/100-go-mistakes-and-how-to-avoid-them https://www.manning.com/books/100-go-mistakes-and-how-to-avo...
- saleh-rz 4y agoI dislike: - Duck Typed interfaces - Unused variables are compiler errors - Lack of Ternary operator - Variable short declaration (:=) - Using case for exported names instead of access modifier
- euroderf 4y agoGo/XML dislikes: XML decoding into structs is an annotational nightmare. XML namespaces are broken and getting no development love. Go/XML likes: Otherwise quite OK.