Live data from Hacker News

What canceled my Go context?

rednafi.com

21–30 of 70 posts

Re: What canceled my Go context?

#22
post #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.

It was a great piece and I learned a lot, thanks for writing it. I hope you didn’t think that it was you I was disappointed with rather than the language designers :)

It’s ironic how context cancellation has the opposite problem as error handling.

With errors they force you to handle every error explicitly which results in people adding unnecessary contextual information: it can be tempting to keep adding layer upon layer of wrapping resulting in an unwieldy error string that’s practically a hand-rolled stacktrace.

With context cancellation OTOH you have to go out of your way to add contextual info at all, and even then it’s not as simple as just using the new machinery because as your piece demonstrates it doesn’t all work well together so you have to go even further out of your way and roll your own timeout-based cancellation. Absurd.

Re: What canceled my Go context?

#23
post #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…

How do it work inside `myFunction1` which is invoked by `myFunction`? Does `myFunction1` needs to be async as well?

Re: What canceled my Go context?

#24
post #18

Earlier quoted context omitted.

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 synta…

Exceptions can be bad if done the wrong way. But the solution isn’t to not deal with it and put it on the programmer. That’s laziness.

The problems are that the signature of functions doesn’t say anything about what values it might throw, and that sometimes the control flow is obscured — an innocuous call throws.

Both of these are solvable.

Re: What canceled my Go context?

#26
post #24
post #18

Earlier quoted context omitted.

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 synta…

Exceptions can be bad if done the wrong way. But the solution isn’t to not deal with it and put it on the programmer. That’s laziness. The problems are that the signature of functions doesn’t say anything about what values it might throw, and that sometimes the control flow is obscured — an innocuous call throws. Both of these are solvable.

Sure but that also feels like a compiler problem. The compiler knows everywhere my function can go. So rather then having it just throw an exception - i.e. arbitrary data - on the stack, surely what's really happening is I'm creating a big union of "result | error[type,type,type,type]" which only gets culled when I add my "exception" handling.

My argument here would be, that all of this though doesn't need to be seen unless its relevant - it seems reasonable that the programmer should be able to write code for the happy path, implicitly understanding there's an error path they should be aware of because errors always happen (I mean, you can straight up run out of memory almost anywhere, for example).

Re: What canceled my Go context?

#27
post #26
post #24

Earlier quoted context omitted.

Exceptions can be bad if done the wrong way. But the solution isn’t to not deal with it and put it on the programmer. That’s laziness. The problems are that the signature of functions doesn’t say anything about what values it might throw, and that sometimes the control flow is obscured — an innocuous call throws. Both of these are solvable.

Sure but that also feels like a compiler problem. The compiler knows everywhere my function can go. So rather then having it just throw an exception - i.e. arbitrary data - on the stack, surely what's really happening is I'm creating a big union of "result | error[type,type,type,type]" which only gets culled when I add my "exception" handling. My argument here would be, that all of this though doesn't need to be seen…

I agree, and I think that the simplicity mantra of the early go team caused them to not deal with solvable problems when they had the chance.

They would rather not solve it, thinking that the "programmers will deal with it".

Now they claim it’s too late.

Re: What canceled my Go context?

#28
post #23
post #20

Earlier quoted context omitted.

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…

How do it work inside `myFunction1` which is invoked by `myFunction`? Does `myFunction1` needs to be async as well?

No, it can be any pure function or IO. Both will get interrupted.

Re: What canceled my Go context?

#29

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…

Go is seen as too boiler plate-ish, and no one likes that. But one of the biggest Go's biggest assets is its simplicity. And it might not be possible to have both simplicity and low boiler plate.

I quite enjoy C# and F# and while they are low boiler plate, you can really learn them in a week or two the way you can learn Go.

And even you don't know anything about Go, you can literally jump into the code base and understand and follow the flow with ease - which quite amazes me.

So unfortunately, every language has trade offs and Go is not an exception.

I can't say I enjoy Go as a language but I find it very, very useful.

And since many people are using LLMs for coding these days, the boiler plate is not as much an issue since it be automated away. And I rather read code generated in Go than some C++ cryptic code.

Re: What canceled my Go context?

#30
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?

Python async tasks can be cancelled. But, I don't think you can attach must context to the cancel (I think you can pass a text message), so it would seem the argument of what go suffered from would apply. (I also think there's some wonkiness with and barriers to understanding Python's implementation that I don't think plagues Go to quite the same extent.)

The current meta is to use task groups and bubble up the exception that cancelled the coroutine/task.
Post reply on HN