Live data from Hacker News

What canceled my Go context?

rednafi.com

11–20 of 70 posts

Re: What canceled my Go context?

#11
post #2

Context cancellation (and it's propagation) is one of the best features in Go. Is there any equivalent in major popular languages like Python, Java, or JS of this?

Java's Virtual Threads (JVM 21) + the Structured Concurrency primitives (not sure exactly what's available in Java 21+) do this natively.

Also, a sibling poster mentioned ZIO/Scala which does the Structured Concurrency thing out of the box.

Re: What canceled my Go context?

#12
It’s great that they identified this (incredibly common) pain point and introduced a way to solve it, but I can’t help being disappointed.

Reading the examples I found myself thinking, “that looks like a really useful pattern, I should bookmark this so I can adopt it whenever I write code like that.”

The fact that I’m considering bookmarking a blog post about complex boilerplate that I would want to use 100% of the times when it’s applicable is a huge red flag and is exactly why people complain about Go.

It feels like you’re constantly fighting the language: having to add error handling boilerplate everywhere and having to pass contexts everywhere (more boilerplate). This is the intersection of those two annoyances so it feels especially annoying (particularly given the nuances/footguns the author describes).

They say the point is that Go forces you to handle errors but 99% of the time that means just returning the error after possibly wrapping it. After a decade of writing Go I still don’t have a good rule of thumb for when I should wrap an error with more info or return it as-is.

I hope someday they make another attempt at a Go 2.0.

Re: What canceled my Go context?

#13

It’s great that they identified this (incredibly common) pain point and introduced a way to solve it, but I can’t help being disappointed. Reading the examples I found myself thinking, “that looks like a really useful pattern, I should bookmark this so I can adopt it whenever I write code like that.” The fact that I’m considering bookmarking a blog post about complex boilerplate that I would want to use 100% of the t…

There are two things I think you could have as implict in Go - error values, and contexts.

Just pass along two hidden variables for both in parameters and returns, and would anything really change that the compiler wouldn't be able to follow?

i.e. most functions return errors, so there should always be an implicit error return possible even if I don't use it. Let the compiler figure out if it needs to generate code for it.

And same story for contexts: why shouldn't a Go program be a giant context tree? If a branch genuinely doesn't ever use it, the compiler should be able to just knock the code out.

Re: What canceled my Go context?

#14
post #2

Context cancellation (and it's propagation) is one of the best features in Go. Is there any equivalent in major popular languages like Python, Java, or JS of this?

Kotlin Coroutine's structured concurrency. Cancelling a parent automatically cancels child jobs, unless explicitly handled not to. https://kotlinlang.org/docs/coroutines-basics.html

Stupidly, child cancellation cancels the parent scope as well, unless the scope opts out by including SupervisorJob.

Re: What canceled my Go context?

#15

It’s great that they identified this (incredibly common) pain point and introduced a way to solve it, but I can’t help being disappointed. Reading the examples I found myself thinking, “that looks like a really useful pattern, I should bookmark this so I can adopt it whenever I write code like that.” The fact that I’m considering bookmarking a blog post about complex boilerplate that I would want to use 100% of the t…

Author here. I absolutely hated writing this piece after shooting myself in the foot a thousand times.

Go's context ergonomics is kinda terrible and currently there's no way around it.

Re: What canceled my Go context?

#16
post #13

It’s great that they identified this (incredibly common) pain point and introduced a way to solve it, but I can’t help being disappointed. Reading the examples I found myself thinking, “that looks like a really useful pattern, I should bookmark this so I can adopt it whenever I write code like that.” The fact that I’m considering bookmarking a blog post about complex boilerplate that I would want to use 100% of the t…

There are two things I think you could have as implict in Go - error values, and contexts. Just pass along two hidden variables for both in parameters and returns, and would anything really change that the compiler wouldn't be able to follow? i.e. most functions return errors, so there should always be an implicit error return possible even if I don't use it. Let the compiler figure out if it needs to generate code f…

What's the difference between an implicit error and exceptions? Being explicit about errors is good. Go's syntactical implementation, coupled with its unexpressive type system, is the problem.

Re: What canceled my Go context?

#17

It’s great that they identified this (incredibly common) pain point and introduced a way to solve it, but I can’t help being disappointed. Reading the examples I found myself thinking, “that looks like a really useful pattern, I should bookmark this so I can adopt it whenever I write code like that.” The fact that I’m considering bookmarking a blog post about complex boilerplate that I would want to use 100% of the t…

I close my nose and always wrap errors with a sentinel error for public functions/methods so that callers can check with `errors.Is`. And you can always identify the place in the call-stack where the error occurred.

I need to start getting used to context with cancel cause - muscle memory hasn't changed yet.

Re: What canceled my Go context?

#18
post #13

Earlier quoted context omitted.

There are two things I think you could have as implict in Go - error values, and contexts. Just pass along two hidden variables for both in parameters and returns, and would anything really change that the compiler wouldn't be able to follow? i.e. most functions return errors, so there should always be an implicit error return possible even if I don't use it. Let the compiler figure out if it needs to generate code f…

What's the difference between an implicit error and exceptions? Being explicit about errors is good. Go's syntactical implementation, coupled with its unexpressive type system, is the problem.

I will freely go on the record as saying that there's nothing wrong with exceptions for this exact reason: errors are so common that a function being "pure" is the exception, and that errors-as-value handling invariable turns into an endless chain of something like "if err; return (nil/zero, err)" in every language which tries it.

The same would apply to anytime you have Result types - ultimately its still just syntactic sugar over "if err then...".

What's far more common in real programs is that an error can occur somewhere where you do not have enough context to handle or resolve it, or you're unaware it can happen. In which case the concept of exceptions is much more valid: "if what do I want to do?" usually only has a couple of places you care about the answer (i.e. "bad thing happened during business process, so start unwinding that process" and many more where the answer is either "crash" or "log it and move on to the next item".

Re: What canceled my Go context?

#19

It’s great that they identified this (incredibly common) pain point and introduced a way to solve it, but I can’t help being disappointed. Reading the examples I found myself thinking, “that looks like a really useful pattern, I should bookmark this so I can adopt it whenever I write code like that.” The fact that I’m considering bookmarking a blog post about complex boilerplate that I would want to use 100% of the t…

I agree go’s error handling feels a bit clunky, though I prefer the local error handling and passing up the chain (if it were a bit more ergonomic) to exceptions, which IMO have a lot of other problems.

The main problems seem to me to be boilerplate and error types being so simplistic (interface just has a method returning a string). Boilerplate definitely seems solvable and a proper error interface too. I tend to use my own error type where I want more info (as in networking errors) but wish Go had an interface with at least error codes that everyone used and was used in the stdlib.

My rule of thumb on annotation is default to no, and add it at the top level. You’ll soon realise if you need more.

How would you fix it if given the chance?

Re: What canceled my Go context?

#20
post #2

Context cancellation (and it's propagation) is one of the best features in Go. Is there any equivalent in major popular languages like Python, Java, or JS of this?

Haskell is the king of cancellation. Using asynchronous exceptions, you can cancel anything, anytime, with user -defined exception types so you know what the cancellation reason is.

Example:

    maybeVal 
Some people think that async exceptions are a pain because you nerd to be prepared that your code can be interrupted any time, but I think it's absolutely worth it because in all the other languages I encounter progress bars that keep running when I click the cancel button, or CLI programs that don't react to CTRL+C.

In Haskell, cancellability is the default and carries no syntax overhead.

This is one of the reasons why I think Haskell is currently the best language for writing IO programs.

Post reply on HN