Go has certainly come a long ways from its initial mission to be a simple language for Rob Pike's simple coworkers. type User struct { Name string `json:"name"` Password string `json:"-"` Email string `json:"email"` } So you can specify how to serialize a struct in json using raw string literals containing arbitrary metadata. And json:"X" means to serialize it to X, except the special value "-" means "omit this one,"…
Go subtleties
131–140 of 190 posts
Re: Go subtleties
#132Great list of why one can love and hate Go. I really did enjoy writing it but you never get the sense that you can be truly certain your code is robust because of subtle behaviour around nil.
I guess as a corollary, Go really rewards writing the dumbest code possible. No advanced type shenanigans, no overuse of interfaces, no complex composition of types. Then you will end up with a very fast, resource light system that just runs forever.
Simplicity is hard. You may see it as dumb, other see it as priceless attribute of the language.
Re: Go subtleties
#133> The wg.Go Function > Go 1.25 introduced a waitgroup.Go function that lets you add Go routines to a waitgroup more easily. It takes the place of using the go keyword, [...] 99% of the time, you don't want to use sync.WaitGroup, but rather errgroup.Group. This is basically sync.WaitGroup with error handling. It also has optional context/cancellation support. See https://pkg.go.dev/golang.org/x/sync/errgroup I know it…
How does it cancel in-progress goroutines when the provided context is cancelled?
Re: Go subtleties
#134Earlier quoted context omitted.
waitgroup's inadequacy is why I end up using structured concurrency like https://github.com/sourcegraph/conc
The last release of this was 2.5 years ago, and it's pre-1.0... is this really ready for production use? Genuinely asking, I'm relatively new to Golang and would love to have a better sense of what parts of the ecosystem are worth learning about.
That said 2.5 years later there’s been many improvements to the stdlib (like waitGroup.Go) such that I no longer feel the need for it going forward.
Re: Go subtleties
#135I had a “wtf” moment when using Go around panic() and recover() I was so surprised by the design choice to need to put recover in in deferred function calls. It’s crazy to smush together the error handling and normal execution code.
func Foo() { try { maybePanic() } catch (err any) { doSomething(err) }
.. more code
}vs
func Foo() { defer func() { if err := recover(); err != nil { doSomething(err) } }()
maybePanic()
.. more code
}Re: Go subtleties
#136> The wg.Go Function > Go 1.25 introduced a waitgroup.Go function that lets you add Go routines to a waitgroup more easily. It takes the place of using the go keyword, [...] 99% of the time, you don't want to use sync.WaitGroup, but rather errgroup.Group. This is basically sync.WaitGroup with error handling. It also has optional context/cancellation support. See https://pkg.go.dev/golang.org/x/sync/errgroup I know it…
Wow how did I not know of this?! How does it cancel in-progress goroutines when the provided context is cancelled?
Re: Go subtleties
#137Great list of why one can love and hate Go. I really did enjoy writing it but you never get the sense that you can be truly certain your code is robust because of subtle behaviour around nil.
As a Go learner, the best explanation that has made sense to me is that interface types essentially just compose two pointers: P1: The type and its method vtable P2: The value Once I understood that I could intuit how a nil Foo was not a nil Bar and not an untyped nil either
willem-dafoe-head-tap.gif
Re: Go subtleties
#138Earlier quoted context omitted.
If it is because of overflow, the idea was that there could be size classes at compile time. A bit like sub/supertyping but for numeric types. A simple type pointer check would be sufficient.
Size classes would save some space and speed up like-to-like comparisons, but wouldn't really do much for unlike comparisons (especially vs. float or complex). Looking only at type pointers fails to account for custom types (e.g., type Foo int); remember that an untyped integer constant can be compared with these. If you want the same semantics at runtime as you get at compile time, I don't see how you can get much s…
Re: Go subtleties
#139> The wg.Go Function > Go 1.25 introduced a waitgroup.Go function that lets you add Go routines to a waitgroup more easily. It takes the place of using the go keyword, [...] 99% of the time, you don't want to use sync.WaitGroup, but rather errgroup.Group. This is basically sync.WaitGroup with error handling. It also has optional context/cancellation support. See https://pkg.go.dev/golang.org/x/sync/errgroup I know it…
>golang.org/x/ is stuff that should be in the standard library but isn't, for some reason think of it as testing/staging before being merged into stable stdlib
Re: Go subtleties
#140Earlier quoted context omitted.
I know it's not exclusive to Go or any language, but you can most certainly write incomprehensible code in it. If anything, expressiveness and proper abstractions can save you from this. I think people often get burnt by bad abstractions in expressive languages, but it's not a problem of the language, but the author's unfamiliarity with the tools at their disposal. If someone starts being clever with abstractions bef…
I like to say this: "Only my code is allowed to be clever" But, on a serious note, I agree with you. Go lacks a lot of power, especially in its type system, that causes a ton of problems (and downtime) that in other languages is trivial to prevent statically.
There is, perhaps, some segment of the developer community who believe that they are infallible and don't need to write tests, but then have the type system exclaim their preconceived notions are wrong, and then come to love the type system for steering them in a better direction, while still remaining oblivious to all the things the incomplete type system is unable to statically assert. But that's a rather bizarre place to be.